xref: /vim-8.2.3635/src/eval.c (revision 4d581a82)
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * eval.c: Expression evaluation.
12  */
13 #define USING_FLOAT_STUFF
14 
15 #include "vim.h"
16 
17 #if defined(FEAT_EVAL) || defined(PROTO)
18 
19 #ifdef AMIGA
20 # include <time.h>	/* for strftime() */
21 #endif
22 
23 #ifdef VMS
24 # include <float.h>
25 #endif
26 
27 #ifdef MACOS
28 # include <time.h>	/* for time_t */
29 #endif
30 
31 #define DICT_MAXNEST 100	/* maximum nesting of lists and dicts */
32 
33 #define DO_NOT_FREE_CNT 99999	/* refcount for dict or list that should not
34 				   be freed. */
35 
36 /*
37  * In a hashtab item "hi_key" points to "di_key" in a dictitem.
38  * This avoids adding a pointer to the hashtab item.
39  * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer.
40  * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer.
41  * HI2DI() converts a hashitem pointer to a dictitem pointer.
42  */
43 static dictitem_T dumdi;
44 #define DI2HIKEY(di) ((di)->di_key)
45 #define HIKEY2DI(p)  ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi)))
46 #define HI2DI(hi)     HIKEY2DI((hi)->hi_key)
47 
48 /*
49  * Structure returned by get_lval() and used by set_var_lval().
50  * For a plain name:
51  *	"name"	    points to the variable name.
52  *	"exp_name"  is NULL.
53  *	"tv"	    is NULL
54  * For a magic braces name:
55  *	"name"	    points to the expanded variable name.
56  *	"exp_name"  is non-NULL, to be freed later.
57  *	"tv"	    is NULL
58  * For an index in a list:
59  *	"name"	    points to the (expanded) variable name.
60  *	"exp_name"  NULL or non-NULL, to be freed later.
61  *	"tv"	    points to the (first) list item value
62  *	"li"	    points to the (first) list item
63  *	"range", "n1", "n2" and "empty2" indicate what items are used.
64  * For an existing Dict item:
65  *	"name"	    points to the (expanded) variable name.
66  *	"exp_name"  NULL or non-NULL, to be freed later.
67  *	"tv"	    points to the dict item value
68  *	"newkey"    is NULL
69  * For a non-existing Dict item:
70  *	"name"	    points to the (expanded) variable name.
71  *	"exp_name"  NULL or non-NULL, to be freed later.
72  *	"tv"	    points to the Dictionary typval_T
73  *	"newkey"    is the key for the new item.
74  */
75 typedef struct lval_S
76 {
77     char_u	*ll_name;	/* start of variable name (can be NULL) */
78     char_u	*ll_exp_name;	/* NULL or expanded name in allocated memory. */
79     typval_T	*ll_tv;		/* Typeval of item being used.  If "newkey"
80 				   isn't NULL it's the Dict to which to add
81 				   the item. */
82     listitem_T	*ll_li;		/* The list item or NULL. */
83     list_T	*ll_list;	/* The list or NULL. */
84     int		ll_range;	/* TRUE when a [i:j] range was used */
85     long	ll_n1;		/* First index for list */
86     long	ll_n2;		/* Second index for list range */
87     int		ll_empty2;	/* Second index is empty: [i:] */
88     dict_T	*ll_dict;	/* The Dictionary or NULL */
89     dictitem_T	*ll_di;		/* The dictitem or NULL */
90     char_u	*ll_newkey;	/* New key for Dict in alloc. mem or NULL. */
91 } lval_T;
92 
93 static char *e_letunexp	= N_("E18: Unexpected characters in :let");
94 static char *e_listidx = N_("E684: list index out of range: %ld");
95 static char *e_undefvar = N_("E121: Undefined variable: %s");
96 static char *e_missbrac = N_("E111: Missing ']'");
97 static char *e_listarg = N_("E686: Argument of %s must be a List");
98 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary");
99 static char *e_listreq = N_("E714: List required");
100 static char *e_dictreq = N_("E715: Dictionary required");
101 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
102 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s");
103 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
104 static char *e_funcdict = N_("E717: Dictionary entry already exists");
105 static char *e_funcref = N_("E718: Funcref required");
106 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
107 static char *e_letwrong = N_("E734: Wrong variable type for %s=");
108 static char *e_nofunc = N_("E130: Unknown function: %s");
109 static char *e_illvar = N_("E461: Illegal variable name: %s");
110 #ifdef FEAT_FLOAT
111 static char *e_float_as_string = N_("E806: using Float as a String");
112 #endif
113 
114 #define NAMESPACE_CHAR	(char_u *)"abglstvw"
115 
116 static dictitem_T	globvars_var;		/* variable used for g: */
117 #define globvarht globvardict.dv_hashtab
118 
119 /*
120  * Old Vim variables such as "v:version" are also available without the "v:".
121  * Also in functions.  We need a special hashtable for them.
122  */
123 static hashtab_T	compat_hashtab;
124 
125 /*
126  * When recursively copying lists and dicts we need to remember which ones we
127  * have done to avoid endless recursiveness.  This unique ID is used for that.
128  * The last bit is used for previous_funccal, ignored when comparing.
129  */
130 static int current_copyID = 0;
131 #define COPYID_INC 2
132 #define COPYID_MASK (~0x1)
133 
134 /* Abort conversion to string after a recursion error. */
135 static int  did_echo_string_emsg = FALSE;
136 
137 /*
138  * Array to hold the hashtab with variables local to each sourced script.
139  * Each item holds a variable (nameless) that points to the dict_T.
140  */
141 typedef struct
142 {
143     dictitem_T	sv_var;
144     dict_T	sv_dict;
145 } scriptvar_T;
146 
147 static garray_T	    ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
148 #define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1])
149 #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
150 
151 static int echo_attr = 0;   /* attributes used for ":echo" */
152 
153 /* Values for trans_function_name() argument: */
154 #define TFN_INT		1	/* internal function name OK */
155 #define TFN_QUIET	2	/* no error messages */
156 #define TFN_NO_AUTOLOAD	4	/* do not use script autoloading */
157 
158 /* Values for get_lval() flags argument: */
159 #define GLV_QUIET	TFN_QUIET	/* no error messages */
160 #define GLV_NO_AUTOLOAD	TFN_NO_AUTOLOAD	/* do not use script autoloading */
161 
162 /*
163  * Structure to hold info for a user function.
164  */
165 typedef struct ufunc ufunc_T;
166 
167 struct ufunc
168 {
169     int		uf_varargs;	/* variable nr of arguments */
170     int		uf_flags;
171     int		uf_calls;	/* nr of active calls */
172     garray_T	uf_args;	/* arguments */
173     garray_T	uf_lines;	/* function lines */
174 #ifdef FEAT_PROFILE
175     int		uf_profiling;	/* TRUE when func is being profiled */
176     /* profiling the function as a whole */
177     int		uf_tm_count;	/* nr of calls */
178     proftime_T	uf_tm_total;	/* time spent in function + children */
179     proftime_T	uf_tm_self;	/* time spent in function itself */
180     proftime_T	uf_tm_children;	/* time spent in children this call */
181     /* profiling the function per line */
182     int		*uf_tml_count;	/* nr of times line was executed */
183     proftime_T	*uf_tml_total;	/* time spent in a line + children */
184     proftime_T	*uf_tml_self;	/* time spent in a line itself */
185     proftime_T	uf_tml_start;	/* start time for current line */
186     proftime_T	uf_tml_children; /* time spent in children for this line */
187     proftime_T	uf_tml_wait;	/* start wait time for current line */
188     int		uf_tml_idx;	/* index of line being timed; -1 if none */
189     int		uf_tml_execed;	/* line being timed was executed */
190 #endif
191     scid_T	uf_script_ID;	/* ID of script where function was defined,
192 				   used for s: variables */
193     int		uf_refcount;	/* for numbered function: reference count */
194     char_u	uf_name[1];	/* name of function (actually longer); can
195 				   start with <SNR>123_ (<SNR> is K_SPECIAL
196 				   KS_EXTRA KE_SNR) */
197 };
198 
199 /* function flags */
200 #define FC_ABORT    1		/* abort function on error */
201 #define FC_RANGE    2		/* function accepts range */
202 #define FC_DICT	    4		/* Dict function, uses "self" */
203 
204 /*
205  * All user-defined functions are found in this hashtable.
206  */
207 static hashtab_T	func_hashtab;
208 
209 /* The names of packages that once were loaded are remembered. */
210 static garray_T		ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
211 
212 /* list heads for garbage collection */
213 static dict_T		*first_dict = NULL;	/* list of all dicts */
214 static list_T		*first_list = NULL;	/* list of all lists */
215 
216 /* From user function to hashitem and back. */
217 static ufunc_T dumuf;
218 #define UF2HIKEY(fp) ((fp)->uf_name)
219 #define HIKEY2UF(p)  ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf)))
220 #define HI2UF(hi)     HIKEY2UF((hi)->hi_key)
221 
222 #define FUNCARG(fp, j)	((char_u **)(fp->uf_args.ga_data))[j]
223 #define FUNCLINE(fp, j)	((char_u **)(fp->uf_lines.ga_data))[j]
224 
225 #define MAX_FUNC_ARGS	20	/* maximum number of function arguments */
226 #define VAR_SHORT_LEN	20	/* short variable name length */
227 #define FIXVAR_CNT	12	/* number of fixed variables */
228 
229 /* structure to hold info for a function that is currently being executed. */
230 typedef struct funccall_S funccall_T;
231 
232 struct funccall_S
233 {
234     ufunc_T	*func;		/* function being called */
235     int		linenr;		/* next line to be executed */
236     int		returned;	/* ":return" used */
237     struct			/* fixed variables for arguments */
238     {
239 	dictitem_T	var;		/* variable (without room for name) */
240 	char_u	room[VAR_SHORT_LEN];	/* room for the name */
241     } fixvar[FIXVAR_CNT];
242     dict_T	l_vars;		/* l: local function variables */
243     dictitem_T	l_vars_var;	/* variable for l: scope */
244     dict_T	l_avars;	/* a: argument variables */
245     dictitem_T	l_avars_var;	/* variable for a: scope */
246     list_T	l_varlist;	/* list for a:000 */
247     listitem_T	l_listitems[MAX_FUNC_ARGS];	/* listitems for a:000 */
248     typval_T	*rettv;		/* return value */
249     linenr_T	breakpoint;	/* next line with breakpoint or zero */
250     int		dbg_tick;	/* debug_tick when breakpoint was set */
251     int		level;		/* top nesting level of executed function */
252 #ifdef FEAT_PROFILE
253     proftime_T	prof_child;	/* time spent in a child */
254 #endif
255     funccall_T	*caller;	/* calling function or NULL */
256 };
257 
258 /*
259  * Info used by a ":for" loop.
260  */
261 typedef struct
262 {
263     int		fi_semicolon;	/* TRUE if ending in '; var]' */
264     int		fi_varcount;	/* nr of variables in the list */
265     listwatch_T	fi_lw;		/* keep an eye on the item used. */
266     list_T	*fi_list;	/* list being used */
267 } forinfo_T;
268 
269 /*
270  * Struct used by trans_function_name()
271  */
272 typedef struct
273 {
274     dict_T	*fd_dict;	/* Dictionary used */
275     char_u	*fd_newkey;	/* new key in "dict" in allocated memory */
276     dictitem_T	*fd_di;		/* Dictionary item used */
277 } funcdict_T;
278 
279 
280 /*
281  * Array to hold the value of v: variables.
282  * The value is in a dictitem, so that it can also be used in the v: scope.
283  * The reason to use this table anyway is for very quick access to the
284  * variables with the VV_ defines.
285  */
286 #include "version.h"
287 
288 /* values for vv_flags: */
289 #define VV_COMPAT	1	/* compatible, also used without "v:" */
290 #define VV_RO		2	/* read-only */
291 #define VV_RO_SBX	4	/* read-only in the sandbox */
292 
293 #define VV_NAME(s, t)	s, {{t, 0, {0}}, 0, {0}}, {0}
294 
295 static struct vimvar
296 {
297     char	*vv_name;	/* name of variable, without v: */
298     dictitem_T	vv_di;		/* value and name for key */
299     char	vv_filler[16];	/* space for LONGEST name below!!! */
300     char	vv_flags;	/* VV_COMPAT, VV_RO, VV_RO_SBX */
301 } vimvars[VV_LEN] =
302 {
303     /*
304      * The order here must match the VV_ defines in vim.h!
305      * Initializing a union does not work, leave tv.vval empty to get zero's.
306      */
307     {VV_NAME("count",		 VAR_NUMBER), VV_COMPAT+VV_RO},
308     {VV_NAME("count1",		 VAR_NUMBER), VV_RO},
309     {VV_NAME("prevcount",	 VAR_NUMBER), VV_RO},
310     {VV_NAME("errmsg",		 VAR_STRING), VV_COMPAT},
311     {VV_NAME("warningmsg",	 VAR_STRING), 0},
312     {VV_NAME("statusmsg",	 VAR_STRING), 0},
313     {VV_NAME("shell_error",	 VAR_NUMBER), VV_COMPAT+VV_RO},
314     {VV_NAME("this_session",	 VAR_STRING), VV_COMPAT},
315     {VV_NAME("version",		 VAR_NUMBER), VV_COMPAT+VV_RO},
316     {VV_NAME("lnum",		 VAR_NUMBER), VV_RO_SBX},
317     {VV_NAME("termresponse",	 VAR_STRING), VV_RO},
318     {VV_NAME("fname",		 VAR_STRING), VV_RO},
319     {VV_NAME("lang",		 VAR_STRING), VV_RO},
320     {VV_NAME("lc_time",		 VAR_STRING), VV_RO},
321     {VV_NAME("ctype",		 VAR_STRING), VV_RO},
322     {VV_NAME("charconvert_from", VAR_STRING), VV_RO},
323     {VV_NAME("charconvert_to",	 VAR_STRING), VV_RO},
324     {VV_NAME("fname_in",	 VAR_STRING), VV_RO},
325     {VV_NAME("fname_out",	 VAR_STRING), VV_RO},
326     {VV_NAME("fname_new",	 VAR_STRING), VV_RO},
327     {VV_NAME("fname_diff",	 VAR_STRING), VV_RO},
328     {VV_NAME("cmdarg",		 VAR_STRING), VV_RO},
329     {VV_NAME("foldstart",	 VAR_NUMBER), VV_RO_SBX},
330     {VV_NAME("foldend",		 VAR_NUMBER), VV_RO_SBX},
331     {VV_NAME("folddashes",	 VAR_STRING), VV_RO_SBX},
332     {VV_NAME("foldlevel",	 VAR_NUMBER), VV_RO_SBX},
333     {VV_NAME("progname",	 VAR_STRING), VV_RO},
334     {VV_NAME("servername",	 VAR_STRING), VV_RO},
335     {VV_NAME("dying",		 VAR_NUMBER), VV_RO},
336     {VV_NAME("exception",	 VAR_STRING), VV_RO},
337     {VV_NAME("throwpoint",	 VAR_STRING), VV_RO},
338     {VV_NAME("register",	 VAR_STRING), VV_RO},
339     {VV_NAME("cmdbang",		 VAR_NUMBER), VV_RO},
340     {VV_NAME("insertmode",	 VAR_STRING), VV_RO},
341     {VV_NAME("val",		 VAR_UNKNOWN), VV_RO},
342     {VV_NAME("key",		 VAR_UNKNOWN), VV_RO},
343     {VV_NAME("profiling",	 VAR_NUMBER), VV_RO},
344     {VV_NAME("fcs_reason",	 VAR_STRING), VV_RO},
345     {VV_NAME("fcs_choice",	 VAR_STRING), 0},
346     {VV_NAME("beval_bufnr",	 VAR_NUMBER), VV_RO},
347     {VV_NAME("beval_winnr",	 VAR_NUMBER), VV_RO},
348     {VV_NAME("beval_lnum",	 VAR_NUMBER), VV_RO},
349     {VV_NAME("beval_col",	 VAR_NUMBER), VV_RO},
350     {VV_NAME("beval_text",	 VAR_STRING), VV_RO},
351     {VV_NAME("scrollstart",	 VAR_STRING), 0},
352     {VV_NAME("swapname",	 VAR_STRING), VV_RO},
353     {VV_NAME("swapchoice",	 VAR_STRING), 0},
354     {VV_NAME("swapcommand",	 VAR_STRING), VV_RO},
355     {VV_NAME("char",		 VAR_STRING), 0},
356     {VV_NAME("mouse_win",	 VAR_NUMBER), 0},
357     {VV_NAME("mouse_lnum",	 VAR_NUMBER), 0},
358     {VV_NAME("mouse_col",	 VAR_NUMBER), 0},
359     {VV_NAME("operator",	 VAR_STRING), VV_RO},
360     {VV_NAME("searchforward",	 VAR_NUMBER), 0},
361     {VV_NAME("hlsearch",	 VAR_NUMBER), 0},
362     {VV_NAME("oldfiles",	 VAR_LIST), 0},
363     {VV_NAME("windowid",	 VAR_NUMBER), VV_RO},
364     {VV_NAME("progpath",	 VAR_STRING), VV_RO},
365     {VV_NAME("completed_item",	 VAR_DICT), VV_RO},
366     {VV_NAME("option_new",	 VAR_STRING), VV_RO},
367     {VV_NAME("option_old",	 VAR_STRING), VV_RO},
368     {VV_NAME("option_type",	 VAR_STRING), VV_RO},
369     {VV_NAME("errors",		 VAR_LIST), 0},
370     {VV_NAME("false",		 VAR_SPECIAL), VV_RO},
371     {VV_NAME("true",		 VAR_SPECIAL), VV_RO},
372     {VV_NAME("null",		 VAR_SPECIAL), VV_RO},
373     {VV_NAME("none",		 VAR_SPECIAL), VV_RO},
374 };
375 
376 /* shorthand */
377 #define vv_type		vv_di.di_tv.v_type
378 #define vv_nr		vv_di.di_tv.vval.v_number
379 #define vv_float	vv_di.di_tv.vval.v_float
380 #define vv_str		vv_di.di_tv.vval.v_string
381 #define vv_list		vv_di.di_tv.vval.v_list
382 #define vv_dict		vv_di.di_tv.vval.v_dict
383 #define vv_tv		vv_di.di_tv
384 
385 static dictitem_T	vimvars_var;		/* variable used for v: */
386 #define vimvarht  vimvardict.dv_hashtab
387 
388 static void prepare_vimvar(int idx, typval_T *save_tv);
389 static void restore_vimvar(int idx, typval_T *save_tv);
390 static int ex_let_vars(char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars);
391 static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon);
392 static char_u *skip_var_one(char_u *arg);
393 static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first);
394 static void list_glob_vars(int *first);
395 static void list_buf_vars(int *first);
396 static void list_win_vars(int *first);
397 #ifdef FEAT_WINDOWS
398 static void list_tab_vars(int *first);
399 #endif
400 static void list_vim_vars(int *first);
401 static void list_script_vars(int *first);
402 static void list_func_vars(int *first);
403 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first);
404 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op);
405 static int check_changedtick(char_u *arg);
406 static char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags);
407 static void clear_lval(lval_T *lp);
408 static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op);
409 static int tv_op(typval_T *tv1, typval_T *tv2, char_u  *op);
410 static void list_fix_watch(list_T *l, listitem_T *item);
411 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep);
412 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit);
413 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock);
414 static void item_lock(typval_T *tv, int deep, int lock);
415 static int tv_islocked(typval_T *tv);
416 
417 static int eval0(char_u *arg,  typval_T *rettv, char_u **nextcmd, int evaluate);
418 static int eval1(char_u **arg, typval_T *rettv, int evaluate);
419 static int eval2(char_u **arg, typval_T *rettv, int evaluate);
420 static int eval3(char_u **arg, typval_T *rettv, int evaluate);
421 static int eval4(char_u **arg, typval_T *rettv, int evaluate);
422 static int eval5(char_u **arg, typval_T *rettv, int evaluate);
423 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string);
424 static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string);
425 
426 static int eval_index(char_u **arg, typval_T *rettv, int evaluate, int verbose);
427 static int get_option_tv(char_u **arg, typval_T *rettv, int evaluate);
428 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate);
429 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate);
430 static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate);
431 static long list_len(list_T *l);
432 static int list_equal(list_T *l1, list_T *l2, int ic, int recursive);
433 static int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive);
434 static int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
435 static long list_find_nr(list_T *l, long idx, int *errorp);
436 static long list_idx_of_item(list_T *l, listitem_T *item);
437 static int list_extend(list_T	*l1, list_T *l2, listitem_T *bef);
438 static int list_concat(list_T *l1, list_T *l2, typval_T *tv);
439 static list_T *list_copy(list_T *orig, int deep, int copyID);
440 static char_u *list2string(typval_T *tv, int copyID);
441 static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap);
442 static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo, int copyID);
443 static int free_unref_items(int copyID);
444 static dictitem_T *dictitem_copy(dictitem_T *org);
445 static void dictitem_remove(dict_T *dict, dictitem_T *item);
446 static dict_T *dict_copy(dict_T *orig, int deep, int copyID);
447 static long dict_len(dict_T *d);
448 static char_u *dict2string(typval_T *tv, int copyID);
449 static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate);
450 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
451 static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
452 static char_u *string_quote(char_u *str, int function);
453 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
454 static int find_internal_func(char_u *name);
455 static char_u *deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload);
456 static int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict);
457 static void emsg_funcname(char *ermsg, char_u *name);
458 static int non_zero_arg(typval_T *argvars);
459 
460 #ifdef FEAT_FLOAT
461 static void f_abs(typval_T *argvars, typval_T *rettv);
462 static void f_acos(typval_T *argvars, typval_T *rettv);
463 #endif
464 static void f_add(typval_T *argvars, typval_T *rettv);
465 static void f_alloc_fail(typval_T *argvars, typval_T *rettv);
466 static void f_and(typval_T *argvars, typval_T *rettv);
467 static void f_append(typval_T *argvars, typval_T *rettv);
468 static void f_argc(typval_T *argvars, typval_T *rettv);
469 static void f_argidx(typval_T *argvars, typval_T *rettv);
470 static void f_arglistid(typval_T *argvars, typval_T *rettv);
471 static void f_argv(typval_T *argvars, typval_T *rettv);
472 static void f_assert_equal(typval_T *argvars, typval_T *rettv);
473 static void f_assert_exception(typval_T *argvars, typval_T *rettv);
474 static void f_assert_fails(typval_T *argvars, typval_T *rettv);
475 static void f_assert_false(typval_T *argvars, typval_T *rettv);
476 static void f_assert_true(typval_T *argvars, typval_T *rettv);
477 #ifdef FEAT_FLOAT
478 static void f_asin(typval_T *argvars, typval_T *rettv);
479 static void f_atan(typval_T *argvars, typval_T *rettv);
480 static void f_atan2(typval_T *argvars, typval_T *rettv);
481 #endif
482 static void f_browse(typval_T *argvars, typval_T *rettv);
483 static void f_browsedir(typval_T *argvars, typval_T *rettv);
484 static void f_bufexists(typval_T *argvars, typval_T *rettv);
485 static void f_buflisted(typval_T *argvars, typval_T *rettv);
486 static void f_bufloaded(typval_T *argvars, typval_T *rettv);
487 static void f_bufname(typval_T *argvars, typval_T *rettv);
488 static void f_bufnr(typval_T *argvars, typval_T *rettv);
489 static void f_bufwinnr(typval_T *argvars, typval_T *rettv);
490 static void f_byte2line(typval_T *argvars, typval_T *rettv);
491 static void byteidx(typval_T *argvars, typval_T *rettv, int comp);
492 static void f_byteidx(typval_T *argvars, typval_T *rettv);
493 static void f_byteidxcomp(typval_T *argvars, typval_T *rettv);
494 static void f_call(typval_T *argvars, typval_T *rettv);
495 #ifdef FEAT_FLOAT
496 static void f_ceil(typval_T *argvars, typval_T *rettv);
497 #endif
498 #ifdef FEAT_JOB_CHANNEL
499 static void f_ch_close(typval_T *argvars, typval_T *rettv);
500 static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv);
501 static void f_ch_evalraw(typval_T *argvars, typval_T *rettv);
502 static void f_ch_getbufnr(typval_T *argvars, typval_T *rettv);
503 static void f_ch_getjob(typval_T *argvars, typval_T *rettv);
504 static void f_ch_log(typval_T *argvars, typval_T *rettv);
505 static void f_ch_logfile(typval_T *argvars, typval_T *rettv);
506 static void f_ch_open(typval_T *argvars, typval_T *rettv);
507 static void f_ch_read(typval_T *argvars, typval_T *rettv);
508 static void f_ch_readraw(typval_T *argvars, typval_T *rettv);
509 static void f_ch_sendexpr(typval_T *argvars, typval_T *rettv);
510 static void f_ch_sendraw(typval_T *argvars, typval_T *rettv);
511 static void f_ch_setoptions(typval_T *argvars, typval_T *rettv);
512 static void f_ch_status(typval_T *argvars, typval_T *rettv);
513 #endif
514 static void f_changenr(typval_T *argvars, typval_T *rettv);
515 static void f_char2nr(typval_T *argvars, typval_T *rettv);
516 static void f_cindent(typval_T *argvars, typval_T *rettv);
517 static void f_clearmatches(typval_T *argvars, typval_T *rettv);
518 static void f_col(typval_T *argvars, typval_T *rettv);
519 #if defined(FEAT_INS_EXPAND)
520 static void f_complete(typval_T *argvars, typval_T *rettv);
521 static void f_complete_add(typval_T *argvars, typval_T *rettv);
522 static void f_complete_check(typval_T *argvars, typval_T *rettv);
523 #endif
524 static void f_confirm(typval_T *argvars, typval_T *rettv);
525 static void f_copy(typval_T *argvars, typval_T *rettv);
526 #ifdef FEAT_FLOAT
527 static void f_cos(typval_T *argvars, typval_T *rettv);
528 static void f_cosh(typval_T *argvars, typval_T *rettv);
529 #endif
530 static void f_count(typval_T *argvars, typval_T *rettv);
531 static void f_cscope_connection(typval_T *argvars, typval_T *rettv);
532 static void f_cursor(typval_T *argsvars, typval_T *rettv);
533 static void f_deepcopy(typval_T *argvars, typval_T *rettv);
534 static void f_delete(typval_T *argvars, typval_T *rettv);
535 static void f_did_filetype(typval_T *argvars, typval_T *rettv);
536 static void f_diff_filler(typval_T *argvars, typval_T *rettv);
537 static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
538 static void f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv);
539 static void f_empty(typval_T *argvars, typval_T *rettv);
540 static void f_escape(typval_T *argvars, typval_T *rettv);
541 static void f_eval(typval_T *argvars, typval_T *rettv);
542 static void f_eventhandler(typval_T *argvars, typval_T *rettv);
543 static void f_executable(typval_T *argvars, typval_T *rettv);
544 static void f_exepath(typval_T *argvars, typval_T *rettv);
545 static void f_exists(typval_T *argvars, typval_T *rettv);
546 #ifdef FEAT_FLOAT
547 static void f_exp(typval_T *argvars, typval_T *rettv);
548 #endif
549 static void f_expand(typval_T *argvars, typval_T *rettv);
550 static void f_extend(typval_T *argvars, typval_T *rettv);
551 static void f_feedkeys(typval_T *argvars, typval_T *rettv);
552 static void f_filereadable(typval_T *argvars, typval_T *rettv);
553 static void f_filewritable(typval_T *argvars, typval_T *rettv);
554 static void f_filter(typval_T *argvars, typval_T *rettv);
555 static void f_finddir(typval_T *argvars, typval_T *rettv);
556 static void f_findfile(typval_T *argvars, typval_T *rettv);
557 #ifdef FEAT_FLOAT
558 static void f_float2nr(typval_T *argvars, typval_T *rettv);
559 static void f_floor(typval_T *argvars, typval_T *rettv);
560 static void f_fmod(typval_T *argvars, typval_T *rettv);
561 #endif
562 static void f_fnameescape(typval_T *argvars, typval_T *rettv);
563 static void f_fnamemodify(typval_T *argvars, typval_T *rettv);
564 static void f_foldclosed(typval_T *argvars, typval_T *rettv);
565 static void f_foldclosedend(typval_T *argvars, typval_T *rettv);
566 static void f_foldlevel(typval_T *argvars, typval_T *rettv);
567 static void f_foldtext(typval_T *argvars, typval_T *rettv);
568 static void f_foldtextresult(typval_T *argvars, typval_T *rettv);
569 static void f_foreground(typval_T *argvars, typval_T *rettv);
570 static void f_function(typval_T *argvars, typval_T *rettv);
571 static void f_garbagecollect(typval_T *argvars, typval_T *rettv);
572 static void f_get(typval_T *argvars, typval_T *rettv);
573 static void f_getbufline(typval_T *argvars, typval_T *rettv);
574 static void f_getbufvar(typval_T *argvars, typval_T *rettv);
575 static void f_getchar(typval_T *argvars, typval_T *rettv);
576 static void f_getcharmod(typval_T *argvars, typval_T *rettv);
577 static void f_getcharsearch(typval_T *argvars, typval_T *rettv);
578 static void f_getcmdline(typval_T *argvars, typval_T *rettv);
579 static void f_getcmdpos(typval_T *argvars, typval_T *rettv);
580 static void f_getcmdtype(typval_T *argvars, typval_T *rettv);
581 static void f_getcmdwintype(typval_T *argvars, typval_T *rettv);
582 static void f_getcwd(typval_T *argvars, typval_T *rettv);
583 static void f_getfontname(typval_T *argvars, typval_T *rettv);
584 static void f_getfperm(typval_T *argvars, typval_T *rettv);
585 static void f_getfsize(typval_T *argvars, typval_T *rettv);
586 static void f_getftime(typval_T *argvars, typval_T *rettv);
587 static void f_getftype(typval_T *argvars, typval_T *rettv);
588 static void f_getline(typval_T *argvars, typval_T *rettv);
589 static void f_getmatches(typval_T *argvars, typval_T *rettv);
590 static void f_getpid(typval_T *argvars, typval_T *rettv);
591 static void f_getcurpos(typval_T *argvars, typval_T *rettv);
592 static void f_getpos(typval_T *argvars, typval_T *rettv);
593 static void f_getqflist(typval_T *argvars, typval_T *rettv);
594 static void f_getreg(typval_T *argvars, typval_T *rettv);
595 static void f_getregtype(typval_T *argvars, typval_T *rettv);
596 static void f_gettabvar(typval_T *argvars, typval_T *rettv);
597 static void f_gettabwinvar(typval_T *argvars, typval_T *rettv);
598 static void f_getwinposx(typval_T *argvars, typval_T *rettv);
599 static void f_getwinposy(typval_T *argvars, typval_T *rettv);
600 static void f_getwinvar(typval_T *argvars, typval_T *rettv);
601 static void f_glob(typval_T *argvars, typval_T *rettv);
602 static void f_globpath(typval_T *argvars, typval_T *rettv);
603 static void f_glob2regpat(typval_T *argvars, typval_T *rettv);
604 static void f_has(typval_T *argvars, typval_T *rettv);
605 static void f_has_key(typval_T *argvars, typval_T *rettv);
606 static void f_haslocaldir(typval_T *argvars, typval_T *rettv);
607 static void f_hasmapto(typval_T *argvars, typval_T *rettv);
608 static void f_histadd(typval_T *argvars, typval_T *rettv);
609 static void f_histdel(typval_T *argvars, typval_T *rettv);
610 static void f_histget(typval_T *argvars, typval_T *rettv);
611 static void f_histnr(typval_T *argvars, typval_T *rettv);
612 static void f_hlID(typval_T *argvars, typval_T *rettv);
613 static void f_hlexists(typval_T *argvars, typval_T *rettv);
614 static void f_hostname(typval_T *argvars, typval_T *rettv);
615 static void f_iconv(typval_T *argvars, typval_T *rettv);
616 static void f_indent(typval_T *argvars, typval_T *rettv);
617 static void f_index(typval_T *argvars, typval_T *rettv);
618 static void f_input(typval_T *argvars, typval_T *rettv);
619 static void f_inputdialog(typval_T *argvars, typval_T *rettv);
620 static void f_inputlist(typval_T *argvars, typval_T *rettv);
621 static void f_inputrestore(typval_T *argvars, typval_T *rettv);
622 static void f_inputsave(typval_T *argvars, typval_T *rettv);
623 static void f_inputsecret(typval_T *argvars, typval_T *rettv);
624 static void f_insert(typval_T *argvars, typval_T *rettv);
625 static void f_invert(typval_T *argvars, typval_T *rettv);
626 static void f_isdirectory(typval_T *argvars, typval_T *rettv);
627 static void f_islocked(typval_T *argvars, typval_T *rettv);
628 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
629 static void f_isnan(typval_T *argvars, typval_T *rettv);
630 #endif
631 static void f_items(typval_T *argvars, typval_T *rettv);
632 #ifdef FEAT_JOB_CHANNEL
633 static void f_job_getchannel(typval_T *argvars, typval_T *rettv);
634 static void f_job_info(typval_T *argvars, typval_T *rettv);
635 static void f_job_setoptions(typval_T *argvars, typval_T *rettv);
636 static void f_job_start(typval_T *argvars, typval_T *rettv);
637 static void f_job_stop(typval_T *argvars, typval_T *rettv);
638 static void f_job_status(typval_T *argvars, typval_T *rettv);
639 #endif
640 static void f_join(typval_T *argvars, typval_T *rettv);
641 static void f_js_decode(typval_T *argvars, typval_T *rettv);
642 static void f_js_encode(typval_T *argvars, typval_T *rettv);
643 static void f_json_decode(typval_T *argvars, typval_T *rettv);
644 static void f_json_encode(typval_T *argvars, typval_T *rettv);
645 static void f_keys(typval_T *argvars, typval_T *rettv);
646 static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv);
647 static void f_len(typval_T *argvars, typval_T *rettv);
648 static void f_libcall(typval_T *argvars, typval_T *rettv);
649 static void f_libcallnr(typval_T *argvars, typval_T *rettv);
650 static void f_line(typval_T *argvars, typval_T *rettv);
651 static void f_line2byte(typval_T *argvars, typval_T *rettv);
652 static void f_lispindent(typval_T *argvars, typval_T *rettv);
653 static void f_localtime(typval_T *argvars, typval_T *rettv);
654 #ifdef FEAT_FLOAT
655 static void f_log(typval_T *argvars, typval_T *rettv);
656 static void f_log10(typval_T *argvars, typval_T *rettv);
657 #endif
658 #ifdef FEAT_LUA
659 static void f_luaeval(typval_T *argvars, typval_T *rettv);
660 #endif
661 static void f_map(typval_T *argvars, typval_T *rettv);
662 static void f_maparg(typval_T *argvars, typval_T *rettv);
663 static void f_mapcheck(typval_T *argvars, typval_T *rettv);
664 static void f_match(typval_T *argvars, typval_T *rettv);
665 static void f_matchadd(typval_T *argvars, typval_T *rettv);
666 static void f_matchaddpos(typval_T *argvars, typval_T *rettv);
667 static void f_matcharg(typval_T *argvars, typval_T *rettv);
668 static void f_matchdelete(typval_T *argvars, typval_T *rettv);
669 static void f_matchend(typval_T *argvars, typval_T *rettv);
670 static void f_matchlist(typval_T *argvars, typval_T *rettv);
671 static void f_matchstr(typval_T *argvars, typval_T *rettv);
672 static void f_max(typval_T *argvars, typval_T *rettv);
673 static void f_min(typval_T *argvars, typval_T *rettv);
674 #ifdef vim_mkdir
675 static void f_mkdir(typval_T *argvars, typval_T *rettv);
676 #endif
677 static void f_mode(typval_T *argvars, typval_T *rettv);
678 #ifdef FEAT_MZSCHEME
679 static void f_mzeval(typval_T *argvars, typval_T *rettv);
680 #endif
681 static void f_nextnonblank(typval_T *argvars, typval_T *rettv);
682 static void f_nr2char(typval_T *argvars, typval_T *rettv);
683 static void f_or(typval_T *argvars, typval_T *rettv);
684 static void f_pathshorten(typval_T *argvars, typval_T *rettv);
685 #ifdef FEAT_PERL
686 static void f_perleval(typval_T *argvars, typval_T *rettv);
687 #endif
688 #ifdef FEAT_FLOAT
689 static void f_pow(typval_T *argvars, typval_T *rettv);
690 #endif
691 static void f_prevnonblank(typval_T *argvars, typval_T *rettv);
692 static void f_printf(typval_T *argvars, typval_T *rettv);
693 static void f_pumvisible(typval_T *argvars, typval_T *rettv);
694 #ifdef FEAT_PYTHON3
695 static void f_py3eval(typval_T *argvars, typval_T *rettv);
696 #endif
697 #ifdef FEAT_PYTHON
698 static void f_pyeval(typval_T *argvars, typval_T *rettv);
699 #endif
700 static void f_range(typval_T *argvars, typval_T *rettv);
701 static void f_readfile(typval_T *argvars, typval_T *rettv);
702 static void f_reltime(typval_T *argvars, typval_T *rettv);
703 #ifdef FEAT_FLOAT
704 static void f_reltimefloat(typval_T *argvars, typval_T *rettv);
705 #endif
706 static void f_reltimestr(typval_T *argvars, typval_T *rettv);
707 static void f_remote_expr(typval_T *argvars, typval_T *rettv);
708 static void f_remote_foreground(typval_T *argvars, typval_T *rettv);
709 static void f_remote_peek(typval_T *argvars, typval_T *rettv);
710 static void f_remote_read(typval_T *argvars, typval_T *rettv);
711 static void f_remote_send(typval_T *argvars, typval_T *rettv);
712 static void f_remove(typval_T *argvars, typval_T *rettv);
713 static void f_rename(typval_T *argvars, typval_T *rettv);
714 static void f_repeat(typval_T *argvars, typval_T *rettv);
715 static void f_resolve(typval_T *argvars, typval_T *rettv);
716 static void f_reverse(typval_T *argvars, typval_T *rettv);
717 #ifdef FEAT_FLOAT
718 static void f_round(typval_T *argvars, typval_T *rettv);
719 #endif
720 static void f_screenattr(typval_T *argvars, typval_T *rettv);
721 static void f_screenchar(typval_T *argvars, typval_T *rettv);
722 static void f_screencol(typval_T *argvars, typval_T *rettv);
723 static void f_screenrow(typval_T *argvars, typval_T *rettv);
724 static void f_search(typval_T *argvars, typval_T *rettv);
725 static void f_searchdecl(typval_T *argvars, typval_T *rettv);
726 static void f_searchpair(typval_T *argvars, typval_T *rettv);
727 static void f_searchpairpos(typval_T *argvars, typval_T *rettv);
728 static void f_searchpos(typval_T *argvars, typval_T *rettv);
729 static void f_server2client(typval_T *argvars, typval_T *rettv);
730 static void f_serverlist(typval_T *argvars, typval_T *rettv);
731 static void f_setbufvar(typval_T *argvars, typval_T *rettv);
732 static void f_setcharsearch(typval_T *argvars, typval_T *rettv);
733 static void f_setcmdpos(typval_T *argvars, typval_T *rettv);
734 static void f_setfperm(typval_T *argvars, typval_T *rettv);
735 static void f_setline(typval_T *argvars, typval_T *rettv);
736 static void f_setloclist(typval_T *argvars, typval_T *rettv);
737 static void f_setmatches(typval_T *argvars, typval_T *rettv);
738 static void f_setpos(typval_T *argvars, typval_T *rettv);
739 static void f_setqflist(typval_T *argvars, typval_T *rettv);
740 static void f_setreg(typval_T *argvars, typval_T *rettv);
741 static void f_settabvar(typval_T *argvars, typval_T *rettv);
742 static void f_settabwinvar(typval_T *argvars, typval_T *rettv);
743 static void f_setwinvar(typval_T *argvars, typval_T *rettv);
744 #ifdef FEAT_CRYPT
745 static void f_sha256(typval_T *argvars, typval_T *rettv);
746 #endif /* FEAT_CRYPT */
747 static void f_shellescape(typval_T *argvars, typval_T *rettv);
748 static void f_shiftwidth(typval_T *argvars, typval_T *rettv);
749 static void f_simplify(typval_T *argvars, typval_T *rettv);
750 #ifdef FEAT_FLOAT
751 static void f_sin(typval_T *argvars, typval_T *rettv);
752 static void f_sinh(typval_T *argvars, typval_T *rettv);
753 #endif
754 static void f_sort(typval_T *argvars, typval_T *rettv);
755 static void f_soundfold(typval_T *argvars, typval_T *rettv);
756 static void f_spellbadword(typval_T *argvars, typval_T *rettv);
757 static void f_spellsuggest(typval_T *argvars, typval_T *rettv);
758 static void f_split(typval_T *argvars, typval_T *rettv);
759 #ifdef FEAT_FLOAT
760 static void f_sqrt(typval_T *argvars, typval_T *rettv);
761 static void f_str2float(typval_T *argvars, typval_T *rettv);
762 #endif
763 static void f_str2nr(typval_T *argvars, typval_T *rettv);
764 static void f_strchars(typval_T *argvars, typval_T *rettv);
765 #ifdef HAVE_STRFTIME
766 static void f_strftime(typval_T *argvars, typval_T *rettv);
767 #endif
768 static void f_stridx(typval_T *argvars, typval_T *rettv);
769 static void f_string(typval_T *argvars, typval_T *rettv);
770 static void f_strlen(typval_T *argvars, typval_T *rettv);
771 static void f_strpart(typval_T *argvars, typval_T *rettv);
772 static void f_strridx(typval_T *argvars, typval_T *rettv);
773 static void f_strtrans(typval_T *argvars, typval_T *rettv);
774 static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv);
775 static void f_strwidth(typval_T *argvars, typval_T *rettv);
776 static void f_submatch(typval_T *argvars, typval_T *rettv);
777 static void f_substitute(typval_T *argvars, typval_T *rettv);
778 static void f_synID(typval_T *argvars, typval_T *rettv);
779 static void f_synIDattr(typval_T *argvars, typval_T *rettv);
780 static void f_synIDtrans(typval_T *argvars, typval_T *rettv);
781 static void f_synstack(typval_T *argvars, typval_T *rettv);
782 static void f_synconcealed(typval_T *argvars, typval_T *rettv);
783 static void f_system(typval_T *argvars, typval_T *rettv);
784 static void f_systemlist(typval_T *argvars, typval_T *rettv);
785 static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv);
786 static void f_tabpagenr(typval_T *argvars, typval_T *rettv);
787 static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv);
788 static void f_taglist(typval_T *argvars, typval_T *rettv);
789 static void f_tagfiles(typval_T *argvars, typval_T *rettv);
790 static void f_tempname(typval_T *argvars, typval_T *rettv);
791 static void f_test(typval_T *argvars, typval_T *rettv);
792 #ifdef FEAT_FLOAT
793 static void f_tan(typval_T *argvars, typval_T *rettv);
794 static void f_tanh(typval_T *argvars, typval_T *rettv);
795 #endif
796 #ifdef FEAT_TIMERS
797 static void f_timer_start(typval_T *argvars, typval_T *rettv);
798 static void f_timer_stop(typval_T *argvars, typval_T *rettv);
799 #endif
800 static void f_tolower(typval_T *argvars, typval_T *rettv);
801 static void f_toupper(typval_T *argvars, typval_T *rettv);
802 static void f_tr(typval_T *argvars, typval_T *rettv);
803 #ifdef FEAT_FLOAT
804 static void f_trunc(typval_T *argvars, typval_T *rettv);
805 #endif
806 static void f_type(typval_T *argvars, typval_T *rettv);
807 static void f_undofile(typval_T *argvars, typval_T *rettv);
808 static void f_undotree(typval_T *argvars, typval_T *rettv);
809 static void f_uniq(typval_T *argvars, typval_T *rettv);
810 static void f_values(typval_T *argvars, typval_T *rettv);
811 static void f_virtcol(typval_T *argvars, typval_T *rettv);
812 static void f_visualmode(typval_T *argvars, typval_T *rettv);
813 static void f_wildmenumode(typval_T *argvars, typval_T *rettv);
814 static void f_win_findbuf(typval_T *argvars, typval_T *rettv);
815 static void f_win_getid(typval_T *argvars, typval_T *rettv);
816 static void f_win_gotoid(typval_T *argvars, typval_T *rettv);
817 static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv);
818 static void f_win_id2win(typval_T *argvars, typval_T *rettv);
819 static void f_winbufnr(typval_T *argvars, typval_T *rettv);
820 static void f_wincol(typval_T *argvars, typval_T *rettv);
821 static void f_winheight(typval_T *argvars, typval_T *rettv);
822 static void f_winline(typval_T *argvars, typval_T *rettv);
823 static void f_winnr(typval_T *argvars, typval_T *rettv);
824 static void f_winrestcmd(typval_T *argvars, typval_T *rettv);
825 static void f_winrestview(typval_T *argvars, typval_T *rettv);
826 static void f_winsaveview(typval_T *argvars, typval_T *rettv);
827 static void f_winwidth(typval_T *argvars, typval_T *rettv);
828 static void f_writefile(typval_T *argvars, typval_T *rettv);
829 static void f_wordcount(typval_T *argvars, typval_T *rettv);
830 static void f_xor(typval_T *argvars, typval_T *rettv);
831 
832 static int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp);
833 static pos_T *var2fpos(typval_T *varp, int dollar_lnum, int *fnum);
834 static int get_env_len(char_u **arg);
835 static int get_id_len(char_u **arg);
836 static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose);
837 static char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int flags);
838 #define FNE_INCL_BR	1	/* find_name_end(): include [] in name */
839 #define FNE_CHECK_START	2	/* find_name_end(): check name starts with
840 				   valid character */
841 static char_u * make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end);
842 static int eval_isnamec(int c);
843 static int eval_isnamec1(int c);
844 static int get_var_tv(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, int no_autoload);
845 static int handle_subscript(char_u **arg, typval_T *rettv, int evaluate, int verbose);
846 static typval_T *alloc_string_tv(char_u *string);
847 static void init_tv(typval_T *varp);
848 #ifdef FEAT_FLOAT
849 static float_T get_tv_float(typval_T *varp);
850 #endif
851 static linenr_T get_tv_lnum(typval_T *argvars);
852 static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf);
853 static dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
854 static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
855 static hashtab_T *find_var_ht(char_u *name, char_u **varname);
856 static funccall_T *get_funccal(void);
857 static void vars_clear_ext(hashtab_T *ht, int free_val);
858 static void delete_var(hashtab_T *ht, hashitem_T *hi);
859 static void list_one_var(dictitem_T *v, char_u *prefix, int *first);
860 static void list_one_var_a(char_u *prefix, char_u *name, int type, char_u *string, int *first);
861 static void set_var(char_u *name, typval_T *varp, int copy);
862 static int var_check_ro(int flags, char_u *name, int use_gettext);
863 static int var_check_fixed(int flags, char_u *name, int use_gettext);
864 static int var_check_func_name(char_u *name, int new_var);
865 static int valid_varname(char_u *varname);
866 static int tv_check_lock(int lock, char_u *name, int use_gettext);
867 static int item_copy(typval_T *from, typval_T *to, int deep, int copyID);
868 static char_u *find_option_end(char_u **arg, int *opt_flags);
869 static char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fd, partial_T **partial);
870 static int eval_fname_script(char_u *p);
871 static int eval_fname_sid(char_u *p);
872 static void list_func_head(ufunc_T *fp, int indent);
873 static ufunc_T *find_func(char_u *name);
874 static int function_exists(char_u *name);
875 static int builtin_function(char_u *name, int len);
876 #ifdef FEAT_PROFILE
877 static void func_do_profile(ufunc_T *fp);
878 static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self);
879 static void prof_func_line(FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self);
880 static int
881 # ifdef __BORLANDC__
882     _RTLENTRYF
883 # endif
884 	prof_total_cmp(const void *s1, const void *s2);
885 static int
886 # ifdef __BORLANDC__
887     _RTLENTRYF
888 # endif
889 	prof_self_cmp(const void *s1, const void *s2);
890 #endif
891 static int script_autoload(char_u *name, int reload);
892 static char_u *autoload_name(char_u *name);
893 static void cat_func_name(char_u *buf, ufunc_T *fp);
894 static void func_free(ufunc_T *fp);
895 static void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict);
896 static int can_free_funccal(funccall_T *fc, int copyID) ;
897 static void free_funccal(funccall_T *fc, int free_val);
898 static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr);
899 static win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp);
900 static win_T *find_tabwin(typval_T *wvp, typval_T *tvp);
901 static void getwinvar(typval_T *argvars, typval_T *rettv, int off);
902 static int searchpair_cmn(typval_T *argvars, pos_T *match_pos);
903 static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp);
904 static void setwinvar(typval_T *argvars, typval_T *rettv, int off);
905 static int write_list(FILE *fd, list_T *list, int binary);
906 static void get_cmd_output_as_rettv(typval_T *argvars, typval_T *rettv, int retlist);
907 
908 
909 #ifdef EBCDIC
910 static int compare_func_name(const void *s1, const void *s2);
911 static void sortFunctions();
912 #endif
913 
914 /*
915  * Initialize the global and v: variables.
916  */
917     void
918 eval_init(void)
919 {
920     int		    i;
921     struct vimvar   *p;
922 
923     init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE);
924     init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE);
925     vimvardict.dv_lock = VAR_FIXED;
926     hash_init(&compat_hashtab);
927     hash_init(&func_hashtab);
928 
929     for (i = 0; i < VV_LEN; ++i)
930     {
931 	p = &vimvars[i];
932 	STRCPY(p->vv_di.di_key, p->vv_name);
933 	if (p->vv_flags & VV_RO)
934 	    p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
935 	else if (p->vv_flags & VV_RO_SBX)
936 	    p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX;
937 	else
938 	    p->vv_di.di_flags = DI_FLAGS_FIX;
939 
940 	/* add to v: scope dict, unless the value is not always available */
941 	if (p->vv_type != VAR_UNKNOWN)
942 	    hash_add(&vimvarht, p->vv_di.di_key);
943 	if (p->vv_flags & VV_COMPAT)
944 	    /* add to compat scope dict */
945 	    hash_add(&compat_hashtab, p->vv_di.di_key);
946     }
947     vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
948 
949     set_vim_var_nr(VV_SEARCHFORWARD, 1L);
950     set_vim_var_nr(VV_HLSEARCH, 1L);
951     set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
952     set_vim_var_list(VV_ERRORS, list_alloc());
953 
954     set_vim_var_nr(VV_FALSE, VVAL_FALSE);
955     set_vim_var_nr(VV_TRUE, VVAL_TRUE);
956     set_vim_var_nr(VV_NONE, VVAL_NONE);
957     set_vim_var_nr(VV_NULL, VVAL_NULL);
958 
959     set_reg_var(0);  /* default for v:register is not 0 but '"' */
960 
961 #ifdef EBCDIC
962     /*
963      * Sort the function table, to enable binary search.
964      */
965     sortFunctions();
966 #endif
967 }
968 
969 #if defined(EXITFREE) || defined(PROTO)
970     void
971 eval_clear(void)
972 {
973     int		    i;
974     struct vimvar   *p;
975 
976     for (i = 0; i < VV_LEN; ++i)
977     {
978 	p = &vimvars[i];
979 	if (p->vv_di.di_tv.v_type == VAR_STRING)
980 	{
981 	    vim_free(p->vv_str);
982 	    p->vv_str = NULL;
983 	}
984 	else if (p->vv_di.di_tv.v_type == VAR_LIST)
985 	{
986 	    list_unref(p->vv_list);
987 	    p->vv_list = NULL;
988 	}
989     }
990     hash_clear(&vimvarht);
991     hash_init(&vimvarht);  /* garbage_collect() will access it */
992     hash_clear(&compat_hashtab);
993 
994     free_scriptnames();
995 # if defined(FEAT_CMDL_COMPL)
996     free_locales();
997 # endif
998 
999     /* global variables */
1000     vars_clear(&globvarht);
1001 
1002     /* autoloaded script names */
1003     ga_clear_strings(&ga_loaded);
1004 
1005     /* Script-local variables. First clear all the variables and in a second
1006      * loop free the scriptvar_T, because a variable in one script might hold
1007      * a reference to the whole scope of another script. */
1008     for (i = 1; i <= ga_scripts.ga_len; ++i)
1009 	vars_clear(&SCRIPT_VARS(i));
1010     for (i = 1; i <= ga_scripts.ga_len; ++i)
1011 	vim_free(SCRIPT_SV(i));
1012     ga_clear(&ga_scripts);
1013 
1014     /* unreferenced lists and dicts */
1015     (void)garbage_collect();
1016 
1017     /* functions */
1018     free_all_functions();
1019     hash_clear(&func_hashtab);
1020 }
1021 #endif
1022 
1023 /*
1024  * Return the name of the executed function.
1025  */
1026     char_u *
1027 func_name(void *cookie)
1028 {
1029     return ((funccall_T *)cookie)->func->uf_name;
1030 }
1031 
1032 /*
1033  * Return the address holding the next breakpoint line for a funccall cookie.
1034  */
1035     linenr_T *
1036 func_breakpoint(void *cookie)
1037 {
1038     return &((funccall_T *)cookie)->breakpoint;
1039 }
1040 
1041 /*
1042  * Return the address holding the debug tick for a funccall cookie.
1043  */
1044     int *
1045 func_dbg_tick(void *cookie)
1046 {
1047     return &((funccall_T *)cookie)->dbg_tick;
1048 }
1049 
1050 /*
1051  * Return the nesting level for a funccall cookie.
1052  */
1053     int
1054 func_level(void *cookie)
1055 {
1056     return ((funccall_T *)cookie)->level;
1057 }
1058 
1059 /* pointer to funccal for currently active function */
1060 funccall_T *current_funccal = NULL;
1061 
1062 /* pointer to list of previously used funccal, still around because some
1063  * item in it is still being used. */
1064 funccall_T *previous_funccal = NULL;
1065 
1066 /*
1067  * Return TRUE when a function was ended by a ":return" command.
1068  */
1069     int
1070 current_func_returned(void)
1071 {
1072     return current_funccal->returned;
1073 }
1074 
1075 
1076 /*
1077  * Set an internal variable to a string value. Creates the variable if it does
1078  * not already exist.
1079  */
1080     void
1081 set_internal_string_var(char_u *name, char_u *value)
1082 {
1083     char_u	*val;
1084     typval_T	*tvp;
1085 
1086     val = vim_strsave(value);
1087     if (val != NULL)
1088     {
1089 	tvp = alloc_string_tv(val);
1090 	if (tvp != NULL)
1091 	{
1092 	    set_var(name, tvp, FALSE);
1093 	    free_tv(tvp);
1094 	}
1095     }
1096 }
1097 
1098 static lval_T	*redir_lval = NULL;
1099 static garray_T redir_ga;	/* only valid when redir_lval is not NULL */
1100 static char_u	*redir_endp = NULL;
1101 static char_u	*redir_varname = NULL;
1102 
1103 /*
1104  * Start recording command output to a variable
1105  * When "append" is TRUE append to an existing variable.
1106  * Returns OK if successfully completed the setup.  FAIL otherwise.
1107  */
1108     int
1109 var_redir_start(char_u *name, int append)
1110 {
1111     int		save_emsg;
1112     int		err;
1113     typval_T	tv;
1114 
1115     /* Catch a bad name early. */
1116     if (!eval_isnamec1(*name))
1117     {
1118 	EMSG(_(e_invarg));
1119 	return FAIL;
1120     }
1121 
1122     /* Make a copy of the name, it is used in redir_lval until redir ends. */
1123     redir_varname = vim_strsave(name);
1124     if (redir_varname == NULL)
1125 	return FAIL;
1126 
1127     redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T));
1128     if (redir_lval == NULL)
1129     {
1130 	var_redir_stop();
1131 	return FAIL;
1132     }
1133 
1134     /* The output is stored in growarray "redir_ga" until redirection ends. */
1135     ga_init2(&redir_ga, (int)sizeof(char), 500);
1136 
1137     /* Parse the variable name (can be a dict or list entry). */
1138     redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
1139 							     FNE_CHECK_START);
1140     if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
1141     {
1142 	clear_lval(redir_lval);
1143 	if (redir_endp != NULL && *redir_endp != NUL)
1144 	    /* Trailing characters are present after the variable name */
1145 	    EMSG(_(e_trailing));
1146 	else
1147 	    EMSG(_(e_invarg));
1148 	redir_endp = NULL;  /* don't store a value, only cleanup */
1149 	var_redir_stop();
1150 	return FAIL;
1151     }
1152 
1153     /* check if we can write to the variable: set it to or append an empty
1154      * string */
1155     save_emsg = did_emsg;
1156     did_emsg = FALSE;
1157     tv.v_type = VAR_STRING;
1158     tv.vval.v_string = (char_u *)"";
1159     if (append)
1160 	set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)".");
1161     else
1162 	set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"=");
1163     clear_lval(redir_lval);
1164     err = did_emsg;
1165     did_emsg |= save_emsg;
1166     if (err)
1167     {
1168 	redir_endp = NULL;  /* don't store a value, only cleanup */
1169 	var_redir_stop();
1170 	return FAIL;
1171     }
1172 
1173     return OK;
1174 }
1175 
1176 /*
1177  * Append "value[value_len]" to the variable set by var_redir_start().
1178  * The actual appending is postponed until redirection ends, because the value
1179  * appended may in fact be the string we write to, changing it may cause freed
1180  * memory to be used:
1181  *   :redir => foo
1182  *   :let foo
1183  *   :redir END
1184  */
1185     void
1186 var_redir_str(char_u *value, int value_len)
1187 {
1188     int		len;
1189 
1190     if (redir_lval == NULL)
1191 	return;
1192 
1193     if (value_len == -1)
1194 	len = (int)STRLEN(value);	/* Append the entire string */
1195     else
1196 	len = value_len;		/* Append only "value_len" characters */
1197 
1198     if (ga_grow(&redir_ga, len) == OK)
1199     {
1200 	mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
1201 	redir_ga.ga_len += len;
1202     }
1203     else
1204 	var_redir_stop();
1205 }
1206 
1207 /*
1208  * Stop redirecting command output to a variable.
1209  * Frees the allocated memory.
1210  */
1211     void
1212 var_redir_stop(void)
1213 {
1214     typval_T	tv;
1215 
1216     if (redir_lval != NULL)
1217     {
1218 	/* If there was no error: assign the text to the variable. */
1219 	if (redir_endp != NULL)
1220 	{
1221 	    ga_append(&redir_ga, NUL);  /* Append the trailing NUL. */
1222 	    tv.v_type = VAR_STRING;
1223 	    tv.vval.v_string = redir_ga.ga_data;
1224 	    /* Call get_lval() again, if it's inside a Dict or List it may
1225 	     * have changed. */
1226 	    redir_endp = get_lval(redir_varname, NULL, redir_lval,
1227 					FALSE, FALSE, 0, FNE_CHECK_START);
1228 	    if (redir_endp != NULL && redir_lval->ll_name != NULL)
1229 		set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
1230 	    clear_lval(redir_lval);
1231 	}
1232 
1233 	/* free the collected output */
1234 	vim_free(redir_ga.ga_data);
1235 	redir_ga.ga_data = NULL;
1236 
1237 	vim_free(redir_lval);
1238 	redir_lval = NULL;
1239     }
1240     vim_free(redir_varname);
1241     redir_varname = NULL;
1242 }
1243 
1244 # if defined(FEAT_MBYTE) || defined(PROTO)
1245     int
1246 eval_charconvert(
1247     char_u	*enc_from,
1248     char_u	*enc_to,
1249     char_u	*fname_from,
1250     char_u	*fname_to)
1251 {
1252     int		err = FALSE;
1253 
1254     set_vim_var_string(VV_CC_FROM, enc_from, -1);
1255     set_vim_var_string(VV_CC_TO, enc_to, -1);
1256     set_vim_var_string(VV_FNAME_IN, fname_from, -1);
1257     set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
1258     if (eval_to_bool(p_ccv, &err, NULL, FALSE))
1259 	err = TRUE;
1260     set_vim_var_string(VV_CC_FROM, NULL, -1);
1261     set_vim_var_string(VV_CC_TO, NULL, -1);
1262     set_vim_var_string(VV_FNAME_IN, NULL, -1);
1263     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
1264 
1265     if (err)
1266 	return FAIL;
1267     return OK;
1268 }
1269 # endif
1270 
1271 # if defined(FEAT_POSTSCRIPT) || defined(PROTO)
1272     int
1273 eval_printexpr(char_u *fname, char_u *args)
1274 {
1275     int		err = FALSE;
1276 
1277     set_vim_var_string(VV_FNAME_IN, fname, -1);
1278     set_vim_var_string(VV_CMDARG, args, -1);
1279     if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
1280 	err = TRUE;
1281     set_vim_var_string(VV_FNAME_IN, NULL, -1);
1282     set_vim_var_string(VV_CMDARG, NULL, -1);
1283 
1284     if (err)
1285     {
1286 	mch_remove(fname);
1287 	return FAIL;
1288     }
1289     return OK;
1290 }
1291 # endif
1292 
1293 # if defined(FEAT_DIFF) || defined(PROTO)
1294     void
1295 eval_diff(
1296     char_u	*origfile,
1297     char_u	*newfile,
1298     char_u	*outfile)
1299 {
1300     int		err = FALSE;
1301 
1302     set_vim_var_string(VV_FNAME_IN, origfile, -1);
1303     set_vim_var_string(VV_FNAME_NEW, newfile, -1);
1304     set_vim_var_string(VV_FNAME_OUT, outfile, -1);
1305     (void)eval_to_bool(p_dex, &err, NULL, FALSE);
1306     set_vim_var_string(VV_FNAME_IN, NULL, -1);
1307     set_vim_var_string(VV_FNAME_NEW, NULL, -1);
1308     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
1309 }
1310 
1311     void
1312 eval_patch(
1313     char_u	*origfile,
1314     char_u	*difffile,
1315     char_u	*outfile)
1316 {
1317     int		err;
1318 
1319     set_vim_var_string(VV_FNAME_IN, origfile, -1);
1320     set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
1321     set_vim_var_string(VV_FNAME_OUT, outfile, -1);
1322     (void)eval_to_bool(p_pex, &err, NULL, FALSE);
1323     set_vim_var_string(VV_FNAME_IN, NULL, -1);
1324     set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
1325     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
1326 }
1327 # endif
1328 
1329 /*
1330  * Top level evaluation function, returning a boolean.
1331  * Sets "error" to TRUE if there was an error.
1332  * Return TRUE or FALSE.
1333  */
1334     int
1335 eval_to_bool(
1336     char_u	*arg,
1337     int		*error,
1338     char_u	**nextcmd,
1339     int		skip)	    /* only parse, don't execute */
1340 {
1341     typval_T	tv;
1342     int		retval = FALSE;
1343 
1344     if (skip)
1345 	++emsg_skip;
1346     if (eval0(arg, &tv, nextcmd, !skip) == FAIL)
1347 	*error = TRUE;
1348     else
1349     {
1350 	*error = FALSE;
1351 	if (!skip)
1352 	{
1353 	    retval = (get_tv_number_chk(&tv, error) != 0);
1354 	    clear_tv(&tv);
1355 	}
1356     }
1357     if (skip)
1358 	--emsg_skip;
1359 
1360     return retval;
1361 }
1362 
1363 /*
1364  * Top level evaluation function, returning a string.  If "skip" is TRUE,
1365  * only parsing to "nextcmd" is done, without reporting errors.  Return
1366  * pointer to allocated memory, or NULL for failure or when "skip" is TRUE.
1367  */
1368     char_u *
1369 eval_to_string_skip(
1370     char_u	*arg,
1371     char_u	**nextcmd,
1372     int		skip)	    /* only parse, don't execute */
1373 {
1374     typval_T	tv;
1375     char_u	*retval;
1376 
1377     if (skip)
1378 	++emsg_skip;
1379     if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip)
1380 	retval = NULL;
1381     else
1382     {
1383 	retval = vim_strsave(get_tv_string(&tv));
1384 	clear_tv(&tv);
1385     }
1386     if (skip)
1387 	--emsg_skip;
1388 
1389     return retval;
1390 }
1391 
1392 /*
1393  * Skip over an expression at "*pp".
1394  * Return FAIL for an error, OK otherwise.
1395  */
1396     int
1397 skip_expr(char_u **pp)
1398 {
1399     typval_T	rettv;
1400 
1401     *pp = skipwhite(*pp);
1402     return eval1(pp, &rettv, FALSE);
1403 }
1404 
1405 /*
1406  * Top level evaluation function, returning a string.
1407  * When "convert" is TRUE convert a List into a sequence of lines and convert
1408  * a Float to a String.
1409  * Return pointer to allocated memory, or NULL for failure.
1410  */
1411     char_u *
1412 eval_to_string(
1413     char_u	*arg,
1414     char_u	**nextcmd,
1415     int		convert)
1416 {
1417     typval_T	tv;
1418     char_u	*retval;
1419     garray_T	ga;
1420 #ifdef FEAT_FLOAT
1421     char_u	numbuf[NUMBUFLEN];
1422 #endif
1423 
1424     if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
1425 	retval = NULL;
1426     else
1427     {
1428 	if (convert && tv.v_type == VAR_LIST)
1429 	{
1430 	    ga_init2(&ga, (int)sizeof(char), 80);
1431 	    if (tv.vval.v_list != NULL)
1432 	    {
1433 		list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0);
1434 		if (tv.vval.v_list->lv_len > 0)
1435 		    ga_append(&ga, NL);
1436 	    }
1437 	    ga_append(&ga, NUL);
1438 	    retval = (char_u *)ga.ga_data;
1439 	}
1440 #ifdef FEAT_FLOAT
1441 	else if (convert && tv.v_type == VAR_FLOAT)
1442 	{
1443 	    vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
1444 	    retval = vim_strsave(numbuf);
1445 	}
1446 #endif
1447 	else
1448 	    retval = vim_strsave(get_tv_string(&tv));
1449 	clear_tv(&tv);
1450     }
1451 
1452     return retval;
1453 }
1454 
1455 /*
1456  * Call eval_to_string() without using current local variables and using
1457  * textlock.  When "use_sandbox" is TRUE use the sandbox.
1458  */
1459     char_u *
1460 eval_to_string_safe(
1461     char_u	*arg,
1462     char_u	**nextcmd,
1463     int		use_sandbox)
1464 {
1465     char_u	*retval;
1466     void	*save_funccalp;
1467 
1468     save_funccalp = save_funccal();
1469     if (use_sandbox)
1470 	++sandbox;
1471     ++textlock;
1472     retval = eval_to_string(arg, nextcmd, FALSE);
1473     if (use_sandbox)
1474 	--sandbox;
1475     --textlock;
1476     restore_funccal(save_funccalp);
1477     return retval;
1478 }
1479 
1480 /*
1481  * Top level evaluation function, returning a number.
1482  * Evaluates "expr" silently.
1483  * Returns -1 for an error.
1484  */
1485     int
1486 eval_to_number(char_u *expr)
1487 {
1488     typval_T	rettv;
1489     int		retval;
1490     char_u	*p = skipwhite(expr);
1491 
1492     ++emsg_off;
1493 
1494     if (eval1(&p, &rettv, TRUE) == FAIL)
1495 	retval = -1;
1496     else
1497     {
1498 	retval = get_tv_number_chk(&rettv, NULL);
1499 	clear_tv(&rettv);
1500     }
1501     --emsg_off;
1502 
1503     return retval;
1504 }
1505 
1506 /*
1507  * Prepare v: variable "idx" to be used.
1508  * Save the current typeval in "save_tv".
1509  * When not used yet add the variable to the v: hashtable.
1510  */
1511     static void
1512 prepare_vimvar(int idx, typval_T *save_tv)
1513 {
1514     *save_tv = vimvars[idx].vv_tv;
1515     if (vimvars[idx].vv_type == VAR_UNKNOWN)
1516 	hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
1517 }
1518 
1519 /*
1520  * Restore v: variable "idx" to typeval "save_tv".
1521  * When no longer defined, remove the variable from the v: hashtable.
1522  */
1523     static void
1524 restore_vimvar(int idx, typval_T *save_tv)
1525 {
1526     hashitem_T	*hi;
1527 
1528     vimvars[idx].vv_tv = *save_tv;
1529     if (vimvars[idx].vv_type == VAR_UNKNOWN)
1530     {
1531 	hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
1532 	if (HASHITEM_EMPTY(hi))
1533 	    EMSG2(_(e_intern2), "restore_vimvar()");
1534 	else
1535 	    hash_remove(&vimvarht, hi);
1536     }
1537 }
1538 
1539 #if defined(FEAT_SPELL) || defined(PROTO)
1540 /*
1541  * Evaluate an expression to a list with suggestions.
1542  * For the "expr:" part of 'spellsuggest'.
1543  * Returns NULL when there is an error.
1544  */
1545     list_T *
1546 eval_spell_expr(char_u *badword, char_u *expr)
1547 {
1548     typval_T	save_val;
1549     typval_T	rettv;
1550     list_T	*list = NULL;
1551     char_u	*p = skipwhite(expr);
1552 
1553     /* Set "v:val" to the bad word. */
1554     prepare_vimvar(VV_VAL, &save_val);
1555     vimvars[VV_VAL].vv_type = VAR_STRING;
1556     vimvars[VV_VAL].vv_str = badword;
1557     if (p_verbose == 0)
1558 	++emsg_off;
1559 
1560     if (eval1(&p, &rettv, TRUE) == OK)
1561     {
1562 	if (rettv.v_type != VAR_LIST)
1563 	    clear_tv(&rettv);
1564 	else
1565 	    list = rettv.vval.v_list;
1566     }
1567 
1568     if (p_verbose == 0)
1569 	--emsg_off;
1570     restore_vimvar(VV_VAL, &save_val);
1571 
1572     return list;
1573 }
1574 
1575 /*
1576  * "list" is supposed to contain two items: a word and a number.  Return the
1577  * word in "pp" and the number as the return value.
1578  * Return -1 if anything isn't right.
1579  * Used to get the good word and score from the eval_spell_expr() result.
1580  */
1581     int
1582 get_spellword(list_T *list, char_u **pp)
1583 {
1584     listitem_T	*li;
1585 
1586     li = list->lv_first;
1587     if (li == NULL)
1588 	return -1;
1589     *pp = get_tv_string(&li->li_tv);
1590 
1591     li = li->li_next;
1592     if (li == NULL)
1593 	return -1;
1594     return get_tv_number(&li->li_tv);
1595 }
1596 #endif
1597 
1598 /*
1599  * Top level evaluation function.
1600  * Returns an allocated typval_T with the result.
1601  * Returns NULL when there is an error.
1602  */
1603     typval_T *
1604 eval_expr(char_u *arg, char_u **nextcmd)
1605 {
1606     typval_T	*tv;
1607 
1608     tv = (typval_T *)alloc(sizeof(typval_T));
1609     if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL)
1610     {
1611 	vim_free(tv);
1612 	tv = NULL;
1613     }
1614 
1615     return tv;
1616 }
1617 
1618 
1619 /*
1620  * Call some vimL function and return the result in "*rettv".
1621  * Uses argv[argc] for the function arguments.  Only Number and String
1622  * arguments are currently supported.
1623  * Returns OK or FAIL.
1624  */
1625     int
1626 call_vim_function(
1627     char_u      *func,
1628     int		argc,
1629     char_u      **argv,
1630     int		safe,		/* use the sandbox */
1631     int		str_arg_only,	/* all arguments are strings */
1632     typval_T	*rettv)
1633 {
1634     typval_T	*argvars;
1635     long	n;
1636     int		len;
1637     int		i;
1638     int		doesrange;
1639     void	*save_funccalp = NULL;
1640     int		ret;
1641 
1642     argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T)));
1643     if (argvars == NULL)
1644 	return FAIL;
1645 
1646     for (i = 0; i < argc; i++)
1647     {
1648 	/* Pass a NULL or empty argument as an empty string */
1649 	if (argv[i] == NULL || *argv[i] == NUL)
1650 	{
1651 	    argvars[i].v_type = VAR_STRING;
1652 	    argvars[i].vval.v_string = (char_u *)"";
1653 	    continue;
1654 	}
1655 
1656 	if (str_arg_only)
1657 	    len = 0;
1658 	else
1659 	    /* Recognize a number argument, the others must be strings. */
1660 	    vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0);
1661 	if (len != 0 && len == (int)STRLEN(argv[i]))
1662 	{
1663 	    argvars[i].v_type = VAR_NUMBER;
1664 	    argvars[i].vval.v_number = n;
1665 	}
1666 	else
1667 	{
1668 	    argvars[i].v_type = VAR_STRING;
1669 	    argvars[i].vval.v_string = argv[i];
1670 	}
1671     }
1672 
1673     if (safe)
1674     {
1675 	save_funccalp = save_funccal();
1676 	++sandbox;
1677     }
1678 
1679     rettv->v_type = VAR_UNKNOWN;		/* clear_tv() uses this */
1680     ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars,
1681 		    curwin->w_cursor.lnum, curwin->w_cursor.lnum,
1682 		    &doesrange, TRUE, NULL, NULL);
1683     if (safe)
1684     {
1685 	--sandbox;
1686 	restore_funccal(save_funccalp);
1687     }
1688     vim_free(argvars);
1689 
1690     if (ret == FAIL)
1691 	clear_tv(rettv);
1692 
1693     return ret;
1694 }
1695 
1696 /*
1697  * Call vimL function "func" and return the result as a number.
1698  * Returns -1 when calling the function fails.
1699  * Uses argv[argc] for the function arguments.
1700  */
1701     long
1702 call_func_retnr(
1703     char_u      *func,
1704     int		argc,
1705     char_u      **argv,
1706     int		safe)		/* use the sandbox */
1707 {
1708     typval_T	rettv;
1709     long	retval;
1710 
1711     /* All arguments are passed as strings, no conversion to number. */
1712     if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
1713 	return -1;
1714 
1715     retval = get_tv_number_chk(&rettv, NULL);
1716     clear_tv(&rettv);
1717     return retval;
1718 }
1719 
1720 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \
1721 	|| defined(FEAT_COMPL_FUNC) || defined(PROTO)
1722 
1723 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
1724 /*
1725  * Call vimL function "func" and return the result as a string.
1726  * Returns NULL when calling the function fails.
1727  * Uses argv[argc] for the function arguments.
1728  */
1729     void *
1730 call_func_retstr(
1731     char_u      *func,
1732     int		argc,
1733     char_u      **argv,
1734     int		safe)		/* use the sandbox */
1735 {
1736     typval_T	rettv;
1737     char_u	*retval;
1738 
1739     /* All arguments are passed as strings, no conversion to number. */
1740     if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
1741 	return NULL;
1742 
1743     retval = vim_strsave(get_tv_string(&rettv));
1744     clear_tv(&rettv);
1745     return retval;
1746 }
1747 # endif
1748 
1749 /*
1750  * Call vimL function "func" and return the result as a List.
1751  * Uses argv[argc] for the function arguments.
1752  * Returns NULL when there is something wrong.
1753  */
1754     void *
1755 call_func_retlist(
1756     char_u      *func,
1757     int		argc,
1758     char_u      **argv,
1759     int		safe)		/* use the sandbox */
1760 {
1761     typval_T	rettv;
1762 
1763     /* All arguments are passed as strings, no conversion to number. */
1764     if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
1765 	return NULL;
1766 
1767     if (rettv.v_type != VAR_LIST)
1768     {
1769 	clear_tv(&rettv);
1770 	return NULL;
1771     }
1772 
1773     return rettv.vval.v_list;
1774 }
1775 #endif
1776 
1777 /*
1778  * Save the current function call pointer, and set it to NULL.
1779  * Used when executing autocommands and for ":source".
1780  */
1781     void *
1782 save_funccal(void)
1783 {
1784     funccall_T *fc = current_funccal;
1785 
1786     current_funccal = NULL;
1787     return (void *)fc;
1788 }
1789 
1790     void
1791 restore_funccal(void *vfc)
1792 {
1793     funccall_T *fc = (funccall_T *)vfc;
1794 
1795     current_funccal = fc;
1796 }
1797 
1798 #if defined(FEAT_PROFILE) || defined(PROTO)
1799 /*
1800  * Prepare profiling for entering a child or something else that is not
1801  * counted for the script/function itself.
1802  * Should always be called in pair with prof_child_exit().
1803  */
1804     void
1805 prof_child_enter(
1806     proftime_T *tm)	/* place to store waittime */
1807 {
1808     funccall_T *fc = current_funccal;
1809 
1810     if (fc != NULL && fc->func->uf_profiling)
1811 	profile_start(&fc->prof_child);
1812     script_prof_save(tm);
1813 }
1814 
1815 /*
1816  * Take care of time spent in a child.
1817  * Should always be called after prof_child_enter().
1818  */
1819     void
1820 prof_child_exit(
1821     proftime_T *tm)	/* where waittime was stored */
1822 {
1823     funccall_T *fc = current_funccal;
1824 
1825     if (fc != NULL && fc->func->uf_profiling)
1826     {
1827 	profile_end(&fc->prof_child);
1828 	profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */
1829 	profile_add(&fc->func->uf_tm_children, &fc->prof_child);
1830 	profile_add(&fc->func->uf_tml_children, &fc->prof_child);
1831     }
1832     script_prof_restore(tm);
1833 }
1834 #endif
1835 
1836 
1837 #ifdef FEAT_FOLDING
1838 /*
1839  * Evaluate 'foldexpr'.  Returns the foldlevel, and any character preceding
1840  * it in "*cp".  Doesn't give error messages.
1841  */
1842     int
1843 eval_foldexpr(char_u *arg, int *cp)
1844 {
1845     typval_T	tv;
1846     int		retval;
1847     char_u	*s;
1848     int		use_sandbox = was_set_insecurely((char_u *)"foldexpr",
1849 								   OPT_LOCAL);
1850 
1851     ++emsg_off;
1852     if (use_sandbox)
1853 	++sandbox;
1854     ++textlock;
1855     *cp = NUL;
1856     if (eval0(arg, &tv, NULL, TRUE) == FAIL)
1857 	retval = 0;
1858     else
1859     {
1860 	/* If the result is a number, just return the number. */
1861 	if (tv.v_type == VAR_NUMBER)
1862 	    retval = tv.vval.v_number;
1863 	else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL)
1864 	    retval = 0;
1865 	else
1866 	{
1867 	    /* If the result is a string, check if there is a non-digit before
1868 	     * the number. */
1869 	    s = tv.vval.v_string;
1870 	    if (!VIM_ISDIGIT(*s) && *s != '-')
1871 		*cp = *s++;
1872 	    retval = atol((char *)s);
1873 	}
1874 	clear_tv(&tv);
1875     }
1876     --emsg_off;
1877     if (use_sandbox)
1878 	--sandbox;
1879     --textlock;
1880 
1881     return retval;
1882 }
1883 #endif
1884 
1885 /*
1886  * ":let"			list all variable values
1887  * ":let var1 var2"		list variable values
1888  * ":let var = expr"		assignment command.
1889  * ":let var += expr"		assignment command.
1890  * ":let var -= expr"		assignment command.
1891  * ":let var .= expr"		assignment command.
1892  * ":let [var1, var2] = expr"	unpack list.
1893  */
1894     void
1895 ex_let(exarg_T *eap)
1896 {
1897     char_u	*arg = eap->arg;
1898     char_u	*expr = NULL;
1899     typval_T	rettv;
1900     int		i;
1901     int		var_count = 0;
1902     int		semicolon = 0;
1903     char_u	op[2];
1904     char_u	*argend;
1905     int		first = TRUE;
1906 
1907     argend = skip_var_list(arg, &var_count, &semicolon);
1908     if (argend == NULL)
1909 	return;
1910     if (argend > arg && argend[-1] == '.')  /* for var.='str' */
1911 	--argend;
1912     expr = skipwhite(argend);
1913     if (*expr != '=' && !(vim_strchr((char_u *)"+-.", *expr) != NULL
1914 			  && expr[1] == '='))
1915     {
1916 	/*
1917 	 * ":let" without "=": list variables
1918 	 */
1919 	if (*arg == '[')
1920 	    EMSG(_(e_invarg));
1921 	else if (!ends_excmd(*arg))
1922 	    /* ":let var1 var2" */
1923 	    arg = list_arg_vars(eap, arg, &first);
1924 	else if (!eap->skip)
1925 	{
1926 	    /* ":let" */
1927 	    list_glob_vars(&first);
1928 	    list_buf_vars(&first);
1929 	    list_win_vars(&first);
1930 #ifdef FEAT_WINDOWS
1931 	    list_tab_vars(&first);
1932 #endif
1933 	    list_script_vars(&first);
1934 	    list_func_vars(&first);
1935 	    list_vim_vars(&first);
1936 	}
1937 	eap->nextcmd = check_nextcmd(arg);
1938     }
1939     else
1940     {
1941 	op[0] = '=';
1942 	op[1] = NUL;
1943 	if (*expr != '=')
1944 	{
1945 	    if (vim_strchr((char_u *)"+-.", *expr) != NULL)
1946 		op[0] = *expr;   /* +=, -= or .= */
1947 	    expr = skipwhite(expr + 2);
1948 	}
1949 	else
1950 	    expr = skipwhite(expr + 1);
1951 
1952 	if (eap->skip)
1953 	    ++emsg_skip;
1954 	i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
1955 	if (eap->skip)
1956 	{
1957 	    if (i != FAIL)
1958 		clear_tv(&rettv);
1959 	    --emsg_skip;
1960 	}
1961 	else if (i != FAIL)
1962 	{
1963 	    (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
1964 									  op);
1965 	    clear_tv(&rettv);
1966 	}
1967     }
1968 }
1969 
1970 /*
1971  * Assign the typevalue "tv" to the variable or variables at "arg_start".
1972  * Handles both "var" with any type and "[var, var; var]" with a list type.
1973  * When "nextchars" is not NULL it points to a string with characters that
1974  * must appear after the variable(s).  Use "+", "-" or "." for add, subtract
1975  * or concatenate.
1976  * Returns OK or FAIL;
1977  */
1978     static int
1979 ex_let_vars(
1980     char_u	*arg_start,
1981     typval_T	*tv,
1982     int		copy,		/* copy values from "tv", don't move */
1983     int		semicolon,	/* from skip_var_list() */
1984     int		var_count,	/* from skip_var_list() */
1985     char_u	*nextchars)
1986 {
1987     char_u	*arg = arg_start;
1988     list_T	*l;
1989     int		i;
1990     listitem_T	*item;
1991     typval_T	ltv;
1992 
1993     if (*arg != '[')
1994     {
1995 	/*
1996 	 * ":let var = expr" or ":for var in list"
1997 	 */
1998 	if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL)
1999 	    return FAIL;
2000 	return OK;
2001     }
2002 
2003     /*
2004      * ":let [v1, v2] = list" or ":for [v1, v2] in listlist"
2005      */
2006     if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL)
2007     {
2008 	EMSG(_(e_listreq));
2009 	return FAIL;
2010     }
2011 
2012     i = list_len(l);
2013     if (semicolon == 0 && var_count < i)
2014     {
2015 	EMSG(_("E687: Less targets than List items"));
2016 	return FAIL;
2017     }
2018     if (var_count - semicolon > i)
2019     {
2020 	EMSG(_("E688: More targets than List items"));
2021 	return FAIL;
2022     }
2023 
2024     item = l->lv_first;
2025     while (*arg != ']')
2026     {
2027 	arg = skipwhite(arg + 1);
2028 	arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars);
2029 	item = item->li_next;
2030 	if (arg == NULL)
2031 	    return FAIL;
2032 
2033 	arg = skipwhite(arg);
2034 	if (*arg == ';')
2035 	{
2036 	    /* Put the rest of the list (may be empty) in the var after ';'.
2037 	     * Create a new list for this. */
2038 	    l = list_alloc();
2039 	    if (l == NULL)
2040 		return FAIL;
2041 	    while (item != NULL)
2042 	    {
2043 		list_append_tv(l, &item->li_tv);
2044 		item = item->li_next;
2045 	    }
2046 
2047 	    ltv.v_type = VAR_LIST;
2048 	    ltv.v_lock = 0;
2049 	    ltv.vval.v_list = l;
2050 	    l->lv_refcount = 1;
2051 
2052 	    arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE,
2053 						    (char_u *)"]", nextchars);
2054 	    clear_tv(&ltv);
2055 	    if (arg == NULL)
2056 		return FAIL;
2057 	    break;
2058 	}
2059 	else if (*arg != ',' && *arg != ']')
2060 	{
2061 	    EMSG2(_(e_intern2), "ex_let_vars()");
2062 	    return FAIL;
2063 	}
2064     }
2065 
2066     return OK;
2067 }
2068 
2069 /*
2070  * Skip over assignable variable "var" or list of variables "[var, var]".
2071  * Used for ":let varvar = expr" and ":for varvar in expr".
2072  * For "[var, var]" increment "*var_count" for each variable.
2073  * for "[var, var; var]" set "semicolon".
2074  * Return NULL for an error.
2075  */
2076     static char_u *
2077 skip_var_list(
2078     char_u	*arg,
2079     int		*var_count,
2080     int		*semicolon)
2081 {
2082     char_u	*p, *s;
2083 
2084     if (*arg == '[')
2085     {
2086 	/* "[var, var]": find the matching ']'. */
2087 	p = arg;
2088 	for (;;)
2089 	{
2090 	    p = skipwhite(p + 1);	/* skip whites after '[', ';' or ',' */
2091 	    s = skip_var_one(p);
2092 	    if (s == p)
2093 	    {
2094 		EMSG2(_(e_invarg2), p);
2095 		return NULL;
2096 	    }
2097 	    ++*var_count;
2098 
2099 	    p = skipwhite(s);
2100 	    if (*p == ']')
2101 		break;
2102 	    else if (*p == ';')
2103 	    {
2104 		if (*semicolon == 1)
2105 		{
2106 		    EMSG(_("Double ; in list of variables"));
2107 		    return NULL;
2108 		}
2109 		*semicolon = 1;
2110 	    }
2111 	    else if (*p != ',')
2112 	    {
2113 		EMSG2(_(e_invarg2), p);
2114 		return NULL;
2115 	    }
2116 	}
2117 	return p + 1;
2118     }
2119     else
2120 	return skip_var_one(arg);
2121 }
2122 
2123 /*
2124  * Skip one (assignable) variable name, including @r, $VAR, &option, d.key,
2125  * l[idx].
2126  */
2127     static char_u *
2128 skip_var_one(char_u *arg)
2129 {
2130     if (*arg == '@' && arg[1] != NUL)
2131 	return arg + 2;
2132     return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
2133 				   NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
2134 }
2135 
2136 /*
2137  * List variables for hashtab "ht" with prefix "prefix".
2138  * If "empty" is TRUE also list NULL strings as empty strings.
2139  */
2140     static void
2141 list_hashtable_vars(
2142     hashtab_T	*ht,
2143     char_u	*prefix,
2144     int		empty,
2145     int		*first)
2146 {
2147     hashitem_T	*hi;
2148     dictitem_T	*di;
2149     int		todo;
2150 
2151     todo = (int)ht->ht_used;
2152     for (hi = ht->ht_array; todo > 0 && !got_int; ++hi)
2153     {
2154 	if (!HASHITEM_EMPTY(hi))
2155 	{
2156 	    --todo;
2157 	    di = HI2DI(hi);
2158 	    if (empty || di->di_tv.v_type != VAR_STRING
2159 					   || di->di_tv.vval.v_string != NULL)
2160 		list_one_var(di, prefix, first);
2161 	}
2162     }
2163 }
2164 
2165 /*
2166  * List global variables.
2167  */
2168     static void
2169 list_glob_vars(int *first)
2170 {
2171     list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
2172 }
2173 
2174 /*
2175  * List buffer variables.
2176  */
2177     static void
2178 list_buf_vars(int *first)
2179 {
2180     char_u	numbuf[NUMBUFLEN];
2181 
2182     list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
2183 								 TRUE, first);
2184 
2185     sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
2186     list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
2187 							       numbuf, first);
2188 }
2189 
2190 /*
2191  * List window variables.
2192  */
2193     static void
2194 list_win_vars(int *first)
2195 {
2196     list_hashtable_vars(&curwin->w_vars->dv_hashtab,
2197 						 (char_u *)"w:", TRUE, first);
2198 }
2199 
2200 #ifdef FEAT_WINDOWS
2201 /*
2202  * List tab page variables.
2203  */
2204     static void
2205 list_tab_vars(int *first)
2206 {
2207     list_hashtable_vars(&curtab->tp_vars->dv_hashtab,
2208 						 (char_u *)"t:", TRUE, first);
2209 }
2210 #endif
2211 
2212 /*
2213  * List Vim variables.
2214  */
2215     static void
2216 list_vim_vars(int *first)
2217 {
2218     list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
2219 }
2220 
2221 /*
2222  * List script-local variables, if there is a script.
2223  */
2224     static void
2225 list_script_vars(int *first)
2226 {
2227     if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
2228 	list_hashtable_vars(&SCRIPT_VARS(current_SID),
2229 						(char_u *)"s:", FALSE, first);
2230 }
2231 
2232 /*
2233  * List function variables, if there is a function.
2234  */
2235     static void
2236 list_func_vars(int *first)
2237 {
2238     if (current_funccal != NULL)
2239 	list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
2240 						(char_u *)"l:", FALSE, first);
2241 }
2242 
2243 /*
2244  * List variables in "arg".
2245  */
2246     static char_u *
2247 list_arg_vars(exarg_T *eap, char_u *arg, int *first)
2248 {
2249     int		error = FALSE;
2250     int		len;
2251     char_u	*name;
2252     char_u	*name_start;
2253     char_u	*arg_subsc;
2254     char_u	*tofree;
2255     typval_T    tv;
2256 
2257     while (!ends_excmd(*arg) && !got_int)
2258     {
2259 	if (error || eap->skip)
2260 	{
2261 	    arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
2262 	    if (!vim_iswhite(*arg) && !ends_excmd(*arg))
2263 	    {
2264 		emsg_severe = TRUE;
2265 		EMSG(_(e_trailing));
2266 		break;
2267 	    }
2268 	}
2269 	else
2270 	{
2271 	    /* get_name_len() takes care of expanding curly braces */
2272 	    name_start = name = arg;
2273 	    len = get_name_len(&arg, &tofree, TRUE, TRUE);
2274 	    if (len <= 0)
2275 	    {
2276 		/* This is mainly to keep test 49 working: when expanding
2277 		 * curly braces fails overrule the exception error message. */
2278 		if (len < 0 && !aborting())
2279 		{
2280 		    emsg_severe = TRUE;
2281 		    EMSG2(_(e_invarg2), arg);
2282 		    break;
2283 		}
2284 		error = TRUE;
2285 	    }
2286 	    else
2287 	    {
2288 		if (tofree != NULL)
2289 		    name = tofree;
2290 		if (get_var_tv(name, len, &tv, NULL, TRUE, FALSE) == FAIL)
2291 		    error = TRUE;
2292 		else
2293 		{
2294 		    /* handle d.key, l[idx], f(expr) */
2295 		    arg_subsc = arg;
2296 		    if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL)
2297 			error = TRUE;
2298 		    else
2299 		    {
2300 			if (arg == arg_subsc && len == 2 && name[1] == ':')
2301 			{
2302 			    switch (*name)
2303 			    {
2304 				case 'g': list_glob_vars(first); break;
2305 				case 'b': list_buf_vars(first); break;
2306 				case 'w': list_win_vars(first); break;
2307 #ifdef FEAT_WINDOWS
2308 				case 't': list_tab_vars(first); break;
2309 #endif
2310 				case 'v': list_vim_vars(first); break;
2311 				case 's': list_script_vars(first); break;
2312 				case 'l': list_func_vars(first); break;
2313 				default:
2314 					  EMSG2(_("E738: Can't list variables for %s"), name);
2315 			    }
2316 			}
2317 			else
2318 			{
2319 			    char_u	numbuf[NUMBUFLEN];
2320 			    char_u	*tf;
2321 			    int		c;
2322 			    char_u	*s;
2323 
2324 			    s = echo_string(&tv, &tf, numbuf, 0);
2325 			    c = *arg;
2326 			    *arg = NUL;
2327 			    list_one_var_a((char_u *)"",
2328 				    arg == arg_subsc ? name : name_start,
2329 				    tv.v_type,
2330 				    s == NULL ? (char_u *)"" : s,
2331 				    first);
2332 			    *arg = c;
2333 			    vim_free(tf);
2334 			}
2335 			clear_tv(&tv);
2336 		    }
2337 		}
2338 	    }
2339 
2340 	    vim_free(tofree);
2341 	}
2342 
2343 	arg = skipwhite(arg);
2344     }
2345 
2346     return arg;
2347 }
2348 
2349 /*
2350  * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value.
2351  * Returns a pointer to the char just after the var name.
2352  * Returns NULL if there is an error.
2353  */
2354     static char_u *
2355 ex_let_one(
2356     char_u	*arg,		/* points to variable name */
2357     typval_T	*tv,		/* value to assign to variable */
2358     int		copy,		/* copy value from "tv" */
2359     char_u	*endchars,	/* valid chars after variable name  or NULL */
2360     char_u	*op)		/* "+", "-", "."  or NULL*/
2361 {
2362     int		c1;
2363     char_u	*name;
2364     char_u	*p;
2365     char_u	*arg_end = NULL;
2366     int		len;
2367     int		opt_flags;
2368     char_u	*tofree = NULL;
2369 
2370     /*
2371      * ":let $VAR = expr": Set environment variable.
2372      */
2373     if (*arg == '$')
2374     {
2375 	/* Find the end of the name. */
2376 	++arg;
2377 	name = arg;
2378 	len = get_env_len(&arg);
2379 	if (len == 0)
2380 	    EMSG2(_(e_invarg2), name - 1);
2381 	else
2382 	{
2383 	    if (op != NULL && (*op == '+' || *op == '-'))
2384 		EMSG2(_(e_letwrong), op);
2385 	    else if (endchars != NULL
2386 			     && vim_strchr(endchars, *skipwhite(arg)) == NULL)
2387 		EMSG(_(e_letunexp));
2388 	    else if (!check_secure())
2389 	    {
2390 		c1 = name[len];
2391 		name[len] = NUL;
2392 		p = get_tv_string_chk(tv);
2393 		if (p != NULL && op != NULL && *op == '.')
2394 		{
2395 		    int	    mustfree = FALSE;
2396 		    char_u  *s = vim_getenv(name, &mustfree);
2397 
2398 		    if (s != NULL)
2399 		    {
2400 			p = tofree = concat_str(s, p);
2401 			if (mustfree)
2402 			    vim_free(s);
2403 		    }
2404 		}
2405 		if (p != NULL)
2406 		{
2407 		    vim_setenv(name, p);
2408 		    if (STRICMP(name, "HOME") == 0)
2409 			init_homedir();
2410 		    else if (didset_vim && STRICMP(name, "VIM") == 0)
2411 			didset_vim = FALSE;
2412 		    else if (didset_vimruntime
2413 					&& STRICMP(name, "VIMRUNTIME") == 0)
2414 			didset_vimruntime = FALSE;
2415 		    arg_end = arg;
2416 		}
2417 		name[len] = c1;
2418 		vim_free(tofree);
2419 	    }
2420 	}
2421     }
2422 
2423     /*
2424      * ":let &option = expr": Set option value.
2425      * ":let &l:option = expr": Set local option value.
2426      * ":let &g:option = expr": Set global option value.
2427      */
2428     else if (*arg == '&')
2429     {
2430 	/* Find the end of the name. */
2431 	p = find_option_end(&arg, &opt_flags);
2432 	if (p == NULL || (endchars != NULL
2433 			      && vim_strchr(endchars, *skipwhite(p)) == NULL))
2434 	    EMSG(_(e_letunexp));
2435 	else
2436 	{
2437 	    long	n;
2438 	    int		opt_type;
2439 	    long	numval;
2440 	    char_u	*stringval = NULL;
2441 	    char_u	*s;
2442 
2443 	    c1 = *p;
2444 	    *p = NUL;
2445 
2446 	    n = get_tv_number(tv);
2447 	    s = get_tv_string_chk(tv);	    /* != NULL if number or string */
2448 	    if (s != NULL && op != NULL && *op != '=')
2449 	    {
2450 		opt_type = get_option_value(arg, &numval,
2451 						       &stringval, opt_flags);
2452 		if ((opt_type == 1 && *op == '.')
2453 			|| (opt_type == 0 && *op != '.'))
2454 		    EMSG2(_(e_letwrong), op);
2455 		else
2456 		{
2457 		    if (opt_type == 1)  /* number */
2458 		    {
2459 			if (*op == '+')
2460 			    n = numval + n;
2461 			else
2462 			    n = numval - n;
2463 		    }
2464 		    else if (opt_type == 0 && stringval != NULL) /* string */
2465 		    {
2466 			s = concat_str(stringval, s);
2467 			vim_free(stringval);
2468 			stringval = s;
2469 		    }
2470 		}
2471 	    }
2472 	    if (s != NULL)
2473 	    {
2474 		set_option_value(arg, n, s, opt_flags);
2475 		arg_end = p;
2476 	    }
2477 	    *p = c1;
2478 	    vim_free(stringval);
2479 	}
2480     }
2481 
2482     /*
2483      * ":let @r = expr": Set register contents.
2484      */
2485     else if (*arg == '@')
2486     {
2487 	++arg;
2488 	if (op != NULL && (*op == '+' || *op == '-'))
2489 	    EMSG2(_(e_letwrong), op);
2490 	else if (endchars != NULL
2491 			 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL)
2492 	    EMSG(_(e_letunexp));
2493 	else
2494 	{
2495 	    char_u	*ptofree = NULL;
2496 	    char_u	*s;
2497 
2498 	    p = get_tv_string_chk(tv);
2499 	    if (p != NULL && op != NULL && *op == '.')
2500 	    {
2501 		s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC);
2502 		if (s != NULL)
2503 		{
2504 		    p = ptofree = concat_str(s, p);
2505 		    vim_free(s);
2506 		}
2507 	    }
2508 	    if (p != NULL)
2509 	    {
2510 		write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE);
2511 		arg_end = arg + 1;
2512 	    }
2513 	    vim_free(ptofree);
2514 	}
2515     }
2516 
2517     /*
2518      * ":let var = expr": Set internal variable.
2519      * ":let {expr} = expr": Idem, name made with curly braces
2520      */
2521     else if (eval_isnamec1(*arg) || *arg == '{')
2522     {
2523 	lval_T	lv;
2524 
2525 	p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START);
2526 	if (p != NULL && lv.ll_name != NULL)
2527 	{
2528 	    if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL)
2529 		EMSG(_(e_letunexp));
2530 	    else
2531 	    {
2532 		set_var_lval(&lv, p, tv, copy, op);
2533 		arg_end = p;
2534 	    }
2535 	}
2536 	clear_lval(&lv);
2537     }
2538 
2539     else
2540 	EMSG2(_(e_invarg2), arg);
2541 
2542     return arg_end;
2543 }
2544 
2545 /*
2546  * If "arg" is equal to "b:changedtick" give an error and return TRUE.
2547  */
2548     static int
2549 check_changedtick(char_u *arg)
2550 {
2551     if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13]))
2552     {
2553 	EMSG2(_(e_readonlyvar), arg);
2554 	return TRUE;
2555     }
2556     return FALSE;
2557 }
2558 
2559 /*
2560  * Get an lval: variable, Dict item or List item that can be assigned a value
2561  * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
2562  * "name.key", "name.key[expr]" etc.
2563  * Indexing only works if "name" is an existing List or Dictionary.
2564  * "name" points to the start of the name.
2565  * If "rettv" is not NULL it points to the value to be assigned.
2566  * "unlet" is TRUE for ":unlet": slightly different behavior when something is
2567  * wrong; must end in space or cmd separator.
2568  *
2569  * flags:
2570  *  GLV_QUIET:       do not give error messages
2571  *  GLV_NO_AUTOLOAD: do not use script autoloading
2572  *
2573  * Returns a pointer to just after the name, including indexes.
2574  * When an evaluation error occurs "lp->ll_name" is NULL;
2575  * Returns NULL for a parsing error.  Still need to free items in "lp"!
2576  */
2577     static char_u *
2578 get_lval(
2579     char_u	*name,
2580     typval_T	*rettv,
2581     lval_T	*lp,
2582     int		unlet,
2583     int		skip,
2584     int		flags,	    /* GLV_ values */
2585     int		fne_flags)  /* flags for find_name_end() */
2586 {
2587     char_u	*p;
2588     char_u	*expr_start, *expr_end;
2589     int		cc;
2590     dictitem_T	*v;
2591     typval_T	var1;
2592     typval_T	var2;
2593     int		empty1 = FALSE;
2594     listitem_T	*ni;
2595     char_u	*key = NULL;
2596     int		len;
2597     hashtab_T	*ht;
2598     int		quiet = flags & GLV_QUIET;
2599 
2600     /* Clear everything in "lp". */
2601     vim_memset(lp, 0, sizeof(lval_T));
2602 
2603     if (skip)
2604     {
2605 	/* When skipping just find the end of the name. */
2606 	lp->ll_name = name;
2607 	return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags);
2608     }
2609 
2610     /* Find the end of the name. */
2611     p = find_name_end(name, &expr_start, &expr_end, fne_flags);
2612     if (expr_start != NULL)
2613     {
2614 	/* Don't expand the name when we already know there is an error. */
2615 	if (unlet && !vim_iswhite(*p) && !ends_excmd(*p)
2616 						    && *p != '[' && *p != '.')
2617 	{
2618 	    EMSG(_(e_trailing));
2619 	    return NULL;
2620 	}
2621 
2622 	lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p);
2623 	if (lp->ll_exp_name == NULL)
2624 	{
2625 	    /* Report an invalid expression in braces, unless the
2626 	     * expression evaluation has been cancelled due to an
2627 	     * aborting error, an interrupt, or an exception. */
2628 	    if (!aborting() && !quiet)
2629 	    {
2630 		emsg_severe = TRUE;
2631 		EMSG2(_(e_invarg2), name);
2632 		return NULL;
2633 	    }
2634 	}
2635 	lp->ll_name = lp->ll_exp_name;
2636     }
2637     else
2638 	lp->ll_name = name;
2639 
2640     /* Without [idx] or .key we are done. */
2641     if ((*p != '[' && *p != '.') || lp->ll_name == NULL)
2642 	return p;
2643 
2644     cc = *p;
2645     *p = NUL;
2646     v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD);
2647     if (v == NULL && !quiet)
2648 	EMSG2(_(e_undefvar), lp->ll_name);
2649     *p = cc;
2650     if (v == NULL)
2651 	return NULL;
2652 
2653     /*
2654      * Loop until no more [idx] or .key is following.
2655      */
2656     lp->ll_tv = &v->di_tv;
2657     while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT))
2658     {
2659 	if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
2660 		&& !(lp->ll_tv->v_type == VAR_DICT
2661 					   && lp->ll_tv->vval.v_dict != NULL))
2662 	{
2663 	    if (!quiet)
2664 		EMSG(_("E689: Can only index a List or Dictionary"));
2665 	    return NULL;
2666 	}
2667 	if (lp->ll_range)
2668 	{
2669 	    if (!quiet)
2670 		EMSG(_("E708: [:] must come last"));
2671 	    return NULL;
2672 	}
2673 
2674 	len = -1;
2675 	if (*p == '.')
2676 	{
2677 	    key = p + 1;
2678 	    for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
2679 		;
2680 	    if (len == 0)
2681 	    {
2682 		if (!quiet)
2683 		    EMSG(_(e_emptykey));
2684 		return NULL;
2685 	    }
2686 	    p = key + len;
2687 	}
2688 	else
2689 	{
2690 	    /* Get the index [expr] or the first index [expr: ]. */
2691 	    p = skipwhite(p + 1);
2692 	    if (*p == ':')
2693 		empty1 = TRUE;
2694 	    else
2695 	    {
2696 		empty1 = FALSE;
2697 		if (eval1(&p, &var1, TRUE) == FAIL)	/* recursive! */
2698 		    return NULL;
2699 		if (get_tv_string_chk(&var1) == NULL)
2700 		{
2701 		    /* not a number or string */
2702 		    clear_tv(&var1);
2703 		    return NULL;
2704 		}
2705 	    }
2706 
2707 	    /* Optionally get the second index [ :expr]. */
2708 	    if (*p == ':')
2709 	    {
2710 		if (lp->ll_tv->v_type == VAR_DICT)
2711 		{
2712 		    if (!quiet)
2713 			EMSG(_(e_dictrange));
2714 		    if (!empty1)
2715 			clear_tv(&var1);
2716 		    return NULL;
2717 		}
2718 		if (rettv != NULL && (rettv->v_type != VAR_LIST
2719 					       || rettv->vval.v_list == NULL))
2720 		{
2721 		    if (!quiet)
2722 			EMSG(_("E709: [:] requires a List value"));
2723 		    if (!empty1)
2724 			clear_tv(&var1);
2725 		    return NULL;
2726 		}
2727 		p = skipwhite(p + 1);
2728 		if (*p == ']')
2729 		    lp->ll_empty2 = TRUE;
2730 		else
2731 		{
2732 		    lp->ll_empty2 = FALSE;
2733 		    if (eval1(&p, &var2, TRUE) == FAIL)	/* recursive! */
2734 		    {
2735 			if (!empty1)
2736 			    clear_tv(&var1);
2737 			return NULL;
2738 		    }
2739 		    if (get_tv_string_chk(&var2) == NULL)
2740 		    {
2741 			/* not a number or string */
2742 			if (!empty1)
2743 			    clear_tv(&var1);
2744 			clear_tv(&var2);
2745 			return NULL;
2746 		    }
2747 		}
2748 		lp->ll_range = TRUE;
2749 	    }
2750 	    else
2751 		lp->ll_range = FALSE;
2752 
2753 	    if (*p != ']')
2754 	    {
2755 		if (!quiet)
2756 		    EMSG(_(e_missbrac));
2757 		if (!empty1)
2758 		    clear_tv(&var1);
2759 		if (lp->ll_range && !lp->ll_empty2)
2760 		    clear_tv(&var2);
2761 		return NULL;
2762 	    }
2763 
2764 	    /* Skip to past ']'. */
2765 	    ++p;
2766 	}
2767 
2768 	if (lp->ll_tv->v_type == VAR_DICT)
2769 	{
2770 	    if (len == -1)
2771 	    {
2772 		/* "[key]": get key from "var1" */
2773 		key = get_tv_string(&var1);	/* is number or string */
2774 		if (*key == NUL)
2775 		{
2776 		    if (!quiet)
2777 			EMSG(_(e_emptykey));
2778 		    clear_tv(&var1);
2779 		    return NULL;
2780 		}
2781 	    }
2782 	    lp->ll_list = NULL;
2783 	    lp->ll_dict = lp->ll_tv->vval.v_dict;
2784 	    lp->ll_di = dict_find(lp->ll_dict, key, len);
2785 
2786 	    /* When assigning to a scope dictionary check that a function and
2787 	     * variable name is valid (only variable name unless it is l: or
2788 	     * g: dictionary). Disallow overwriting a builtin function. */
2789 	    if (rettv != NULL && lp->ll_dict->dv_scope != 0)
2790 	    {
2791 		int prevval;
2792 		int wrong;
2793 
2794 		if (len != -1)
2795 		{
2796 		    prevval = key[len];
2797 		    key[len] = NUL;
2798 		}
2799 		else
2800 		    prevval = 0; /* avoid compiler warning */
2801 		wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
2802 			       && rettv->v_type == VAR_FUNC
2803 			       && var_check_func_name(key, lp->ll_di == NULL))
2804 			|| !valid_varname(key);
2805 		if (len != -1)
2806 		    key[len] = prevval;
2807 		if (wrong)
2808 		    return NULL;
2809 	    }
2810 
2811 	    if (lp->ll_di == NULL)
2812 	    {
2813 		/* Can't add "v:" variable. */
2814 		if (lp->ll_dict == &vimvardict)
2815 		{
2816 		    EMSG2(_(e_illvar), name);
2817 		    return NULL;
2818 		}
2819 
2820 		/* Key does not exist in dict: may need to add it. */
2821 		if (*p == '[' || *p == '.' || unlet)
2822 		{
2823 		    if (!quiet)
2824 			EMSG2(_(e_dictkey), key);
2825 		    if (len == -1)
2826 			clear_tv(&var1);
2827 		    return NULL;
2828 		}
2829 		if (len == -1)
2830 		    lp->ll_newkey = vim_strsave(key);
2831 		else
2832 		    lp->ll_newkey = vim_strnsave(key, len);
2833 		if (len == -1)
2834 		    clear_tv(&var1);
2835 		if (lp->ll_newkey == NULL)
2836 		    p = NULL;
2837 		break;
2838 	    }
2839 	    /* existing variable, need to check if it can be changed */
2840 	    else if (var_check_ro(lp->ll_di->di_flags, name, FALSE))
2841 		return NULL;
2842 
2843 	    if (len == -1)
2844 		clear_tv(&var1);
2845 	    lp->ll_tv = &lp->ll_di->di_tv;
2846 	}
2847 	else
2848 	{
2849 	    /*
2850 	     * Get the number and item for the only or first index of the List.
2851 	     */
2852 	    if (empty1)
2853 		lp->ll_n1 = 0;
2854 	    else
2855 	    {
2856 		lp->ll_n1 = get_tv_number(&var1);   /* is number or string */
2857 		clear_tv(&var1);
2858 	    }
2859 	    lp->ll_dict = NULL;
2860 	    lp->ll_list = lp->ll_tv->vval.v_list;
2861 	    lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
2862 	    if (lp->ll_li == NULL)
2863 	    {
2864 		if (lp->ll_n1 < 0)
2865 		{
2866 		    lp->ll_n1 = 0;
2867 		    lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
2868 		}
2869 	    }
2870 	    if (lp->ll_li == NULL)
2871 	    {
2872 		if (lp->ll_range && !lp->ll_empty2)
2873 		    clear_tv(&var2);
2874 		if (!quiet)
2875 		    EMSGN(_(e_listidx), lp->ll_n1);
2876 		return NULL;
2877 	    }
2878 
2879 	    /*
2880 	     * May need to find the item or absolute index for the second
2881 	     * index of a range.
2882 	     * When no index given: "lp->ll_empty2" is TRUE.
2883 	     * Otherwise "lp->ll_n2" is set to the second index.
2884 	     */
2885 	    if (lp->ll_range && !lp->ll_empty2)
2886 	    {
2887 		lp->ll_n2 = get_tv_number(&var2);   /* is number or string */
2888 		clear_tv(&var2);
2889 		if (lp->ll_n2 < 0)
2890 		{
2891 		    ni = list_find(lp->ll_list, lp->ll_n2);
2892 		    if (ni == NULL)
2893 		    {
2894 			if (!quiet)
2895 			    EMSGN(_(e_listidx), lp->ll_n2);
2896 			return NULL;
2897 		    }
2898 		    lp->ll_n2 = list_idx_of_item(lp->ll_list, ni);
2899 		}
2900 
2901 		/* Check that lp->ll_n2 isn't before lp->ll_n1. */
2902 		if (lp->ll_n1 < 0)
2903 		    lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
2904 		if (lp->ll_n2 < lp->ll_n1)
2905 		{
2906 		    if (!quiet)
2907 			EMSGN(_(e_listidx), lp->ll_n2);
2908 		    return NULL;
2909 		}
2910 	    }
2911 
2912 	    lp->ll_tv = &lp->ll_li->li_tv;
2913 	}
2914     }
2915 
2916     return p;
2917 }
2918 
2919 /*
2920  * Clear lval "lp" that was filled by get_lval().
2921  */
2922     static void
2923 clear_lval(lval_T *lp)
2924 {
2925     vim_free(lp->ll_exp_name);
2926     vim_free(lp->ll_newkey);
2927 }
2928 
2929 /*
2930  * Set a variable that was parsed by get_lval() to "rettv".
2931  * "endp" points to just after the parsed name.
2932  * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=".
2933  */
2934     static void
2935 set_var_lval(
2936     lval_T	*lp,
2937     char_u	*endp,
2938     typval_T	*rettv,
2939     int		copy,
2940     char_u	*op)
2941 {
2942     int		cc;
2943     listitem_T	*ri;
2944     dictitem_T	*di;
2945 
2946     if (lp->ll_tv == NULL)
2947     {
2948 	if (!check_changedtick(lp->ll_name))
2949 	{
2950 	    cc = *endp;
2951 	    *endp = NUL;
2952 	    if (op != NULL && *op != '=')
2953 	    {
2954 		typval_T tv;
2955 
2956 		/* handle +=, -= and .= */
2957 		di = NULL;
2958 		if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
2959 						 &tv, &di, TRUE, FALSE) == OK)
2960 		{
2961 		    if ((di == NULL
2962 			   || (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
2963 			      && !tv_check_lock(di->di_tv.v_lock, lp->ll_name,
2964 								      FALSE)))
2965 			    && tv_op(&tv, rettv, op) == OK)
2966 			set_var(lp->ll_name, &tv, FALSE);
2967 		    clear_tv(&tv);
2968 		}
2969 	    }
2970 	    else
2971 		set_var(lp->ll_name, rettv, copy);
2972 	    *endp = cc;
2973 	}
2974     }
2975     else if (tv_check_lock(lp->ll_newkey == NULL
2976 		? lp->ll_tv->v_lock
2977 		: lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE))
2978 	;
2979     else if (lp->ll_range)
2980     {
2981 	listitem_T *ll_li = lp->ll_li;
2982 	int ll_n1 = lp->ll_n1;
2983 
2984 	/*
2985 	 * Check whether any of the list items is locked
2986 	 */
2987 	for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; )
2988 	{
2989 	    if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE))
2990 		return;
2991 	    ri = ri->li_next;
2992 	    if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == ll_n1))
2993 		break;
2994 	    ll_li = ll_li->li_next;
2995 	    ++ll_n1;
2996 	}
2997 
2998 	/*
2999 	 * Assign the List values to the list items.
3000 	 */
3001 	for (ri = rettv->vval.v_list->lv_first; ri != NULL; )
3002 	{
3003 	    if (op != NULL && *op != '=')
3004 		tv_op(&lp->ll_li->li_tv, &ri->li_tv, op);
3005 	    else
3006 	    {
3007 		clear_tv(&lp->ll_li->li_tv);
3008 		copy_tv(&ri->li_tv, &lp->ll_li->li_tv);
3009 	    }
3010 	    ri = ri->li_next;
3011 	    if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1))
3012 		break;
3013 	    if (lp->ll_li->li_next == NULL)
3014 	    {
3015 		/* Need to add an empty item. */
3016 		if (list_append_number(lp->ll_list, 0) == FAIL)
3017 		{
3018 		    ri = NULL;
3019 		    break;
3020 		}
3021 	    }
3022 	    lp->ll_li = lp->ll_li->li_next;
3023 	    ++lp->ll_n1;
3024 	}
3025 	if (ri != NULL)
3026 	    EMSG(_("E710: List value has more items than target"));
3027 	else if (lp->ll_empty2
3028 		? (lp->ll_li != NULL && lp->ll_li->li_next != NULL)
3029 		: lp->ll_n1 != lp->ll_n2)
3030 	    EMSG(_("E711: List value has not enough items"));
3031     }
3032     else
3033     {
3034 	/*
3035 	 * Assign to a List or Dictionary item.
3036 	 */
3037 	if (lp->ll_newkey != NULL)
3038 	{
3039 	    if (op != NULL && *op != '=')
3040 	    {
3041 		EMSG2(_(e_letwrong), op);
3042 		return;
3043 	    }
3044 
3045 	    /* Need to add an item to the Dictionary. */
3046 	    di = dictitem_alloc(lp->ll_newkey);
3047 	    if (di == NULL)
3048 		return;
3049 	    if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL)
3050 	    {
3051 		vim_free(di);
3052 		return;
3053 	    }
3054 	    lp->ll_tv = &di->di_tv;
3055 	}
3056 	else if (op != NULL && *op != '=')
3057 	{
3058 	    tv_op(lp->ll_tv, rettv, op);
3059 	    return;
3060 	}
3061 	else
3062 	    clear_tv(lp->ll_tv);
3063 
3064 	/*
3065 	 * Assign the value to the variable or list item.
3066 	 */
3067 	if (copy)
3068 	    copy_tv(rettv, lp->ll_tv);
3069 	else
3070 	{
3071 	    *lp->ll_tv = *rettv;
3072 	    lp->ll_tv->v_lock = 0;
3073 	    init_tv(rettv);
3074 	}
3075     }
3076 }
3077 
3078 /*
3079  * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2"
3080  * Returns OK or FAIL.
3081  */
3082     static int
3083 tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
3084 {
3085     long	n;
3086     char_u	numbuf[NUMBUFLEN];
3087     char_u	*s;
3088 
3089     /* Can't do anything with a Funcref, Dict, v:true on the right. */
3090     if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
3091 						&& tv2->v_type != VAR_SPECIAL)
3092     {
3093 	switch (tv1->v_type)
3094 	{
3095 	    case VAR_UNKNOWN:
3096 	    case VAR_DICT:
3097 	    case VAR_FUNC:
3098 	    case VAR_PARTIAL:
3099 	    case VAR_SPECIAL:
3100 	    case VAR_JOB:
3101 	    case VAR_CHANNEL:
3102 		break;
3103 
3104 	    case VAR_LIST:
3105 		if (*op != '+' || tv2->v_type != VAR_LIST)
3106 		    break;
3107 		/* List += List */
3108 		if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL)
3109 		    list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
3110 		return OK;
3111 
3112 	    case VAR_NUMBER:
3113 	    case VAR_STRING:
3114 		if (tv2->v_type == VAR_LIST)
3115 		    break;
3116 		if (*op == '+' || *op == '-')
3117 		{
3118 		    /* nr += nr  or  nr -= nr*/
3119 		    n = get_tv_number(tv1);
3120 #ifdef FEAT_FLOAT
3121 		    if (tv2->v_type == VAR_FLOAT)
3122 		    {
3123 			float_T f = n;
3124 
3125 			if (*op == '+')
3126 			    f += tv2->vval.v_float;
3127 			else
3128 			    f -= tv2->vval.v_float;
3129 			clear_tv(tv1);
3130 			tv1->v_type = VAR_FLOAT;
3131 			tv1->vval.v_float = f;
3132 		    }
3133 		    else
3134 #endif
3135 		    {
3136 			if (*op == '+')
3137 			    n += get_tv_number(tv2);
3138 			else
3139 			    n -= get_tv_number(tv2);
3140 			clear_tv(tv1);
3141 			tv1->v_type = VAR_NUMBER;
3142 			tv1->vval.v_number = n;
3143 		    }
3144 		}
3145 		else
3146 		{
3147 		    if (tv2->v_type == VAR_FLOAT)
3148 			break;
3149 
3150 		    /* str .= str */
3151 		    s = get_tv_string(tv1);
3152 		    s = concat_str(s, get_tv_string_buf(tv2, numbuf));
3153 		    clear_tv(tv1);
3154 		    tv1->v_type = VAR_STRING;
3155 		    tv1->vval.v_string = s;
3156 		}
3157 		return OK;
3158 
3159 	    case VAR_FLOAT:
3160 #ifdef FEAT_FLOAT
3161 		{
3162 		    float_T f;
3163 
3164 		    if (*op == '.' || (tv2->v_type != VAR_FLOAT
3165 				    && tv2->v_type != VAR_NUMBER
3166 				    && tv2->v_type != VAR_STRING))
3167 			break;
3168 		    if (tv2->v_type == VAR_FLOAT)
3169 			f = tv2->vval.v_float;
3170 		    else
3171 			f = get_tv_number(tv2);
3172 		    if (*op == '+')
3173 			tv1->vval.v_float += f;
3174 		    else
3175 			tv1->vval.v_float -= f;
3176 		}
3177 #endif
3178 		return OK;
3179 	}
3180     }
3181 
3182     EMSG2(_(e_letwrong), op);
3183     return FAIL;
3184 }
3185 
3186 /*
3187  * Add a watcher to a list.
3188  */
3189     void
3190 list_add_watch(list_T *l, listwatch_T *lw)
3191 {
3192     lw->lw_next = l->lv_watch;
3193     l->lv_watch = lw;
3194 }
3195 
3196 /*
3197  * Remove a watcher from a list.
3198  * No warning when it isn't found...
3199  */
3200     void
3201 list_rem_watch(list_T *l, listwatch_T *lwrem)
3202 {
3203     listwatch_T	*lw, **lwp;
3204 
3205     lwp = &l->lv_watch;
3206     for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
3207     {
3208 	if (lw == lwrem)
3209 	{
3210 	    *lwp = lw->lw_next;
3211 	    break;
3212 	}
3213 	lwp = &lw->lw_next;
3214     }
3215 }
3216 
3217 /*
3218  * Just before removing an item from a list: advance watchers to the next
3219  * item.
3220  */
3221     static void
3222 list_fix_watch(list_T *l, listitem_T *item)
3223 {
3224     listwatch_T	*lw;
3225 
3226     for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
3227 	if (lw->lw_item == item)
3228 	    lw->lw_item = item->li_next;
3229 }
3230 
3231 /*
3232  * Evaluate the expression used in a ":for var in expr" command.
3233  * "arg" points to "var".
3234  * Set "*errp" to TRUE for an error, FALSE otherwise;
3235  * Return a pointer that holds the info.  Null when there is an error.
3236  */
3237     void *
3238 eval_for_line(
3239     char_u	*arg,
3240     int		*errp,
3241     char_u	**nextcmdp,
3242     int		skip)
3243 {
3244     forinfo_T	*fi;
3245     char_u	*expr;
3246     typval_T	tv;
3247     list_T	*l;
3248 
3249     *errp = TRUE;	/* default: there is an error */
3250 
3251     fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T));
3252     if (fi == NULL)
3253 	return NULL;
3254 
3255     expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
3256     if (expr == NULL)
3257 	return fi;
3258 
3259     expr = skipwhite(expr);
3260     if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2]))
3261     {
3262 	EMSG(_("E690: Missing \"in\" after :for"));
3263 	return fi;
3264     }
3265 
3266     if (skip)
3267 	++emsg_skip;
3268     if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK)
3269     {
3270 	*errp = FALSE;
3271 	if (!skip)
3272 	{
3273 	    l = tv.vval.v_list;
3274 	    if (tv.v_type != VAR_LIST || l == NULL)
3275 	    {
3276 		EMSG(_(e_listreq));
3277 		clear_tv(&tv);
3278 	    }
3279 	    else
3280 	    {
3281 		/* No need to increment the refcount, it's already set for the
3282 		 * list being used in "tv". */
3283 		fi->fi_list = l;
3284 		list_add_watch(l, &fi->fi_lw);
3285 		fi->fi_lw.lw_item = l->lv_first;
3286 	    }
3287 	}
3288     }
3289     if (skip)
3290 	--emsg_skip;
3291 
3292     return fi;
3293 }
3294 
3295 /*
3296  * Use the first item in a ":for" list.  Advance to the next.
3297  * Assign the values to the variable (list).  "arg" points to the first one.
3298  * Return TRUE when a valid item was found, FALSE when at end of list or
3299  * something wrong.
3300  */
3301     int
3302 next_for_item(void *fi_void, char_u *arg)
3303 {
3304     forinfo_T	*fi = (forinfo_T *)fi_void;
3305     int		result;
3306     listitem_T	*item;
3307 
3308     item = fi->fi_lw.lw_item;
3309     if (item == NULL)
3310 	result = FALSE;
3311     else
3312     {
3313 	fi->fi_lw.lw_item = item->li_next;
3314 	result = (ex_let_vars(arg, &item->li_tv, TRUE,
3315 			      fi->fi_semicolon, fi->fi_varcount, NULL) == OK);
3316     }
3317     return result;
3318 }
3319 
3320 /*
3321  * Free the structure used to store info used by ":for".
3322  */
3323     void
3324 free_for_info(void *fi_void)
3325 {
3326     forinfo_T    *fi = (forinfo_T *)fi_void;
3327 
3328     if (fi != NULL && fi->fi_list != NULL)
3329     {
3330 	list_rem_watch(fi->fi_list, &fi->fi_lw);
3331 	list_unref(fi->fi_list);
3332     }
3333     vim_free(fi);
3334 }
3335 
3336 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
3337 
3338     void
3339 set_context_for_expression(
3340     expand_T	*xp,
3341     char_u	*arg,
3342     cmdidx_T	cmdidx)
3343 {
3344     int		got_eq = FALSE;
3345     int		c;
3346     char_u	*p;
3347 
3348     if (cmdidx == CMD_let)
3349     {
3350 	xp->xp_context = EXPAND_USER_VARS;
3351 	if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL)
3352 	{
3353 	    /* ":let var1 var2 ...": find last space. */
3354 	    for (p = arg + STRLEN(arg); p >= arg; )
3355 	    {
3356 		xp->xp_pattern = p;
3357 		mb_ptr_back(arg, p);
3358 		if (vim_iswhite(*p))
3359 		    break;
3360 	    }
3361 	    return;
3362 	}
3363     }
3364     else
3365 	xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS
3366 							  : EXPAND_EXPRESSION;
3367     while ((xp->xp_pattern = vim_strpbrk(arg,
3368 				  (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL)
3369     {
3370 	c = *xp->xp_pattern;
3371 	if (c == '&')
3372 	{
3373 	    c = xp->xp_pattern[1];
3374 	    if (c == '&')
3375 	    {
3376 		++xp->xp_pattern;
3377 		xp->xp_context = cmdidx != CMD_let || got_eq
3378 					 ? EXPAND_EXPRESSION : EXPAND_NOTHING;
3379 	    }
3380 	    else if (c != ' ')
3381 	    {
3382 		xp->xp_context = EXPAND_SETTINGS;
3383 		if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':')
3384 		    xp->xp_pattern += 2;
3385 
3386 	    }
3387 	}
3388 	else if (c == '$')
3389 	{
3390 	    /* environment variable */
3391 	    xp->xp_context = EXPAND_ENV_VARS;
3392 	}
3393 	else if (c == '=')
3394 	{
3395 	    got_eq = TRUE;
3396 	    xp->xp_context = EXPAND_EXPRESSION;
3397 	}
3398 	else if ((c == '<' || c == '#')
3399 		&& xp->xp_context == EXPAND_FUNCTIONS
3400 		&& vim_strchr(xp->xp_pattern, '(') == NULL)
3401 	{
3402 	    /* Function name can start with "<SNR>" and contain '#'. */
3403 	    break;
3404 	}
3405 	else if (cmdidx != CMD_let || got_eq)
3406 	{
3407 	    if (c == '"')	    /* string */
3408 	    {
3409 		while ((c = *++xp->xp_pattern) != NUL && c != '"')
3410 		    if (c == '\\' && xp->xp_pattern[1] != NUL)
3411 			++xp->xp_pattern;
3412 		xp->xp_context = EXPAND_NOTHING;
3413 	    }
3414 	    else if (c == '\'')	    /* literal string */
3415 	    {
3416 		/* Trick: '' is like stopping and starting a literal string. */
3417 		while ((c = *++xp->xp_pattern) != NUL && c != '\'')
3418 		    /* skip */ ;
3419 		xp->xp_context = EXPAND_NOTHING;
3420 	    }
3421 	    else if (c == '|')
3422 	    {
3423 		if (xp->xp_pattern[1] == '|')
3424 		{
3425 		    ++xp->xp_pattern;
3426 		    xp->xp_context = EXPAND_EXPRESSION;
3427 		}
3428 		else
3429 		    xp->xp_context = EXPAND_COMMANDS;
3430 	    }
3431 	    else
3432 		xp->xp_context = EXPAND_EXPRESSION;
3433 	}
3434 	else
3435 	    /* Doesn't look like something valid, expand as an expression
3436 	     * anyway. */
3437 	    xp->xp_context = EXPAND_EXPRESSION;
3438 	arg = xp->xp_pattern;
3439 	if (*arg != NUL)
3440 	    while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
3441 		/* skip */ ;
3442     }
3443     xp->xp_pattern = arg;
3444 }
3445 
3446 #endif /* FEAT_CMDL_COMPL */
3447 
3448 /*
3449  * ":1,25call func(arg1, arg2)"	function call.
3450  */
3451     void
3452 ex_call(exarg_T *eap)
3453 {
3454     char_u	*arg = eap->arg;
3455     char_u	*startarg;
3456     char_u	*name;
3457     char_u	*tofree;
3458     int		len;
3459     typval_T	rettv;
3460     linenr_T	lnum;
3461     int		doesrange;
3462     int		failed = FALSE;
3463     funcdict_T	fudi;
3464     partial_T	*partial = NULL;
3465 
3466     if (eap->skip)
3467     {
3468 	/* trans_function_name() doesn't work well when skipping, use eval0()
3469 	 * instead to skip to any following command, e.g. for:
3470 	 *   :if 0 | call dict.foo().bar() | endif  */
3471 	++emsg_skip;
3472 	if (eval0(eap->arg, &rettv, &eap->nextcmd, FALSE) != FAIL)
3473 	    clear_tv(&rettv);
3474 	--emsg_skip;
3475 	return;
3476     }
3477 
3478     tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi, &partial);
3479     if (fudi.fd_newkey != NULL)
3480     {
3481 	/* Still need to give an error message for missing key. */
3482 	EMSG2(_(e_dictkey), fudi.fd_newkey);
3483 	vim_free(fudi.fd_newkey);
3484     }
3485     if (tofree == NULL)
3486 	return;
3487 
3488     /* Increase refcount on dictionary, it could get deleted when evaluating
3489      * the arguments. */
3490     if (fudi.fd_dict != NULL)
3491 	++fudi.fd_dict->dv_refcount;
3492 
3493     /* If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its
3494      * contents.  For VAR_PARTIAL get its partial, unless we already have one
3495      * from trans_function_name(). */
3496     len = (int)STRLEN(tofree);
3497     name = deref_func_name(tofree, &len,
3498 				    partial != NULL ? NULL : &partial, FALSE);
3499 
3500     /* Skip white space to allow ":call func ()".  Not good, but required for
3501      * backward compatibility. */
3502     startarg = skipwhite(arg);
3503     rettv.v_type = VAR_UNKNOWN;	/* clear_tv() uses this */
3504 
3505     if (*startarg != '(')
3506     {
3507 	EMSG2(_("E107: Missing parentheses: %s"), eap->arg);
3508 	goto end;
3509     }
3510 
3511     /*
3512      * When skipping, evaluate the function once, to find the end of the
3513      * arguments.
3514      * When the function takes a range, this is discovered after the first
3515      * call, and the loop is broken.
3516      */
3517     if (eap->skip)
3518     {
3519 	++emsg_skip;
3520 	lnum = eap->line2;	/* do it once, also with an invalid range */
3521     }
3522     else
3523 	lnum = eap->line1;
3524     for ( ; lnum <= eap->line2; ++lnum)
3525     {
3526 	if (!eap->skip && eap->addr_count > 0)
3527 	{
3528 	    curwin->w_cursor.lnum = lnum;
3529 	    curwin->w_cursor.col = 0;
3530 #ifdef FEAT_VIRTUALEDIT
3531 	    curwin->w_cursor.coladd = 0;
3532 #endif
3533 	}
3534 	arg = startarg;
3535 	if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg,
3536 		    eap->line1, eap->line2, &doesrange,
3537 				   !eap->skip, partial, fudi.fd_dict) == FAIL)
3538 	{
3539 	    failed = TRUE;
3540 	    break;
3541 	}
3542 
3543 	/* Handle a function returning a Funcref, Dictionary or List. */
3544 	if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL)
3545 	{
3546 	    failed = TRUE;
3547 	    break;
3548 	}
3549 
3550 	clear_tv(&rettv);
3551 	if (doesrange || eap->skip)
3552 	    break;
3553 
3554 	/* Stop when immediately aborting on error, or when an interrupt
3555 	 * occurred or an exception was thrown but not caught.
3556 	 * get_func_tv() returned OK, so that the check for trailing
3557 	 * characters below is executed. */
3558 	if (aborting())
3559 	    break;
3560     }
3561     if (eap->skip)
3562 	--emsg_skip;
3563 
3564     if (!failed)
3565     {
3566 	/* Check for trailing illegal characters and a following command. */
3567 	if (!ends_excmd(*arg))
3568 	{
3569 	    emsg_severe = TRUE;
3570 	    EMSG(_(e_trailing));
3571 	}
3572 	else
3573 	    eap->nextcmd = check_nextcmd(arg);
3574     }
3575 
3576 end:
3577     dict_unref(fudi.fd_dict);
3578     vim_free(tofree);
3579 }
3580 
3581 /*
3582  * ":unlet[!] var1 ... " command.
3583  */
3584     void
3585 ex_unlet(exarg_T *eap)
3586 {
3587     ex_unletlock(eap, eap->arg, 0);
3588 }
3589 
3590 /*
3591  * ":lockvar" and ":unlockvar" commands
3592  */
3593     void
3594 ex_lockvar(exarg_T *eap)
3595 {
3596     char_u	*arg = eap->arg;
3597     int		deep = 2;
3598 
3599     if (eap->forceit)
3600 	deep = -1;
3601     else if (vim_isdigit(*arg))
3602     {
3603 	deep = getdigits(&arg);
3604 	arg = skipwhite(arg);
3605     }
3606 
3607     ex_unletlock(eap, arg, deep);
3608 }
3609 
3610 /*
3611  * ":unlet", ":lockvar" and ":unlockvar" are quite similar.
3612  */
3613     static void
3614 ex_unletlock(
3615     exarg_T	*eap,
3616     char_u	*argstart,
3617     int		deep)
3618 {
3619     char_u	*arg = argstart;
3620     char_u	*name_end;
3621     int		error = FALSE;
3622     lval_T	lv;
3623 
3624     do
3625     {
3626 	/* Parse the name and find the end. */
3627 	name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0,
3628 							     FNE_CHECK_START);
3629 	if (lv.ll_name == NULL)
3630 	    error = TRUE;	    /* error but continue parsing */
3631 	if (name_end == NULL || (!vim_iswhite(*name_end)
3632 						   && !ends_excmd(*name_end)))
3633 	{
3634 	    if (name_end != NULL)
3635 	    {
3636 		emsg_severe = TRUE;
3637 		EMSG(_(e_trailing));
3638 	    }
3639 	    if (!(eap->skip || error))
3640 		clear_lval(&lv);
3641 	    break;
3642 	}
3643 
3644 	if (!error && !eap->skip)
3645 	{
3646 	    if (eap->cmdidx == CMD_unlet)
3647 	    {
3648 		if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL)
3649 		    error = TRUE;
3650 	    }
3651 	    else
3652 	    {
3653 		if (do_lock_var(&lv, name_end, deep,
3654 					  eap->cmdidx == CMD_lockvar) == FAIL)
3655 		    error = TRUE;
3656 	    }
3657 	}
3658 
3659 	if (!eap->skip)
3660 	    clear_lval(&lv);
3661 
3662 	arg = skipwhite(name_end);
3663     } while (!ends_excmd(*arg));
3664 
3665     eap->nextcmd = check_nextcmd(arg);
3666 }
3667 
3668     static int
3669 do_unlet_var(
3670     lval_T	*lp,
3671     char_u	*name_end,
3672     int		forceit)
3673 {
3674     int		ret = OK;
3675     int		cc;
3676 
3677     if (lp->ll_tv == NULL)
3678     {
3679 	cc = *name_end;
3680 	*name_end = NUL;
3681 
3682 	/* Normal name or expanded name. */
3683 	if (check_changedtick(lp->ll_name))
3684 	    ret = FAIL;
3685 	else if (do_unlet(lp->ll_name, forceit) == FAIL)
3686 	    ret = FAIL;
3687 	*name_end = cc;
3688     }
3689     else if ((lp->ll_list != NULL
3690 		   && tv_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE))
3691 	    || (lp->ll_dict != NULL
3692 		  && tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE)))
3693 	return FAIL;
3694     else if (lp->ll_range)
3695     {
3696 	listitem_T    *li;
3697 	listitem_T    *ll_li = lp->ll_li;
3698 	int	      ll_n1 = lp->ll_n1;
3699 
3700 	while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1))
3701 	{
3702 	    li = ll_li->li_next;
3703 	    if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE))
3704 		return FAIL;
3705 	    ll_li = li;
3706 	    ++ll_n1;
3707 	}
3708 
3709 	/* Delete a range of List items. */
3710 	while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1))
3711 	{
3712 	    li = lp->ll_li->li_next;
3713 	    listitem_remove(lp->ll_list, lp->ll_li);
3714 	    lp->ll_li = li;
3715 	    ++lp->ll_n1;
3716 	}
3717     }
3718     else
3719     {
3720 	if (lp->ll_list != NULL)
3721 	    /* unlet a List item. */
3722 	    listitem_remove(lp->ll_list, lp->ll_li);
3723 	else
3724 	    /* unlet a Dictionary item. */
3725 	    dictitem_remove(lp->ll_dict, lp->ll_di);
3726     }
3727 
3728     return ret;
3729 }
3730 
3731 /*
3732  * "unlet" a variable.  Return OK if it existed, FAIL if not.
3733  * When "forceit" is TRUE don't complain if the variable doesn't exist.
3734  */
3735     int
3736 do_unlet(char_u *name, int forceit)
3737 {
3738     hashtab_T	*ht;
3739     hashitem_T	*hi;
3740     char_u	*varname;
3741     dict_T	*d;
3742     dictitem_T	*di;
3743 
3744     ht = find_var_ht(name, &varname);
3745     if (ht != NULL && *varname != NUL)
3746     {
3747 	if (ht == &globvarht)
3748 	    d = &globvardict;
3749 	else if (current_funccal != NULL
3750 			     && ht == &current_funccal->l_vars.dv_hashtab)
3751 	    d = &current_funccal->l_vars;
3752 	else if (ht == &compat_hashtab)
3753 	    d = &vimvardict;
3754 	else
3755 	{
3756 	    di = find_var_in_ht(ht, *name, (char_u *)"", FALSE);
3757 	    d = di == NULL ? NULL : di->di_tv.vval.v_dict;
3758 	}
3759 	if (d == NULL)
3760 	{
3761 	    EMSG2(_(e_intern2), "do_unlet()");
3762 	    return FAIL;
3763 	}
3764 	hi = hash_find(ht, varname);
3765 	if (!HASHITEM_EMPTY(hi))
3766 	{
3767 	    di = HI2DI(hi);
3768 	    if (var_check_fixed(di->di_flags, name, FALSE)
3769 		    || var_check_ro(di->di_flags, name, FALSE)
3770 		    || tv_check_lock(d->dv_lock, name, FALSE))
3771 		return FAIL;
3772 
3773 	    delete_var(ht, hi);
3774 	    return OK;
3775 	}
3776     }
3777     if (forceit)
3778 	return OK;
3779     EMSG2(_("E108: No such variable: \"%s\""), name);
3780     return FAIL;
3781 }
3782 
3783 /*
3784  * Lock or unlock variable indicated by "lp".
3785  * "deep" is the levels to go (-1 for unlimited);
3786  * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar".
3787  */
3788     static int
3789 do_lock_var(
3790     lval_T	*lp,
3791     char_u	*name_end,
3792     int		deep,
3793     int		lock)
3794 {
3795     int		ret = OK;
3796     int		cc;
3797     dictitem_T	*di;
3798 
3799     if (deep == 0)	/* nothing to do */
3800 	return OK;
3801 
3802     if (lp->ll_tv == NULL)
3803     {
3804 	cc = *name_end;
3805 	*name_end = NUL;
3806 
3807 	/* Normal name or expanded name. */
3808 	if (check_changedtick(lp->ll_name))
3809 	    ret = FAIL;
3810 	else
3811 	{
3812 	    di = find_var(lp->ll_name, NULL, TRUE);
3813 	    if (di == NULL)
3814 		ret = FAIL;
3815 	    else
3816 	    {
3817 		if (lock)
3818 		    di->di_flags |= DI_FLAGS_LOCK;
3819 		else
3820 		    di->di_flags &= ~DI_FLAGS_LOCK;
3821 		item_lock(&di->di_tv, deep, lock);
3822 	    }
3823 	}
3824 	*name_end = cc;
3825     }
3826     else if (lp->ll_range)
3827     {
3828 	listitem_T    *li = lp->ll_li;
3829 
3830 	/* (un)lock a range of List items. */
3831 	while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1))
3832 	{
3833 	    item_lock(&li->li_tv, deep, lock);
3834 	    li = li->li_next;
3835 	    ++lp->ll_n1;
3836 	}
3837     }
3838     else if (lp->ll_list != NULL)
3839 	/* (un)lock a List item. */
3840 	item_lock(&lp->ll_li->li_tv, deep, lock);
3841     else
3842 	/* (un)lock a Dictionary item. */
3843 	item_lock(&lp->ll_di->di_tv, deep, lock);
3844 
3845     return ret;
3846 }
3847 
3848 /*
3849  * Lock or unlock an item.  "deep" is nr of levels to go.
3850  */
3851     static void
3852 item_lock(typval_T *tv, int deep, int lock)
3853 {
3854     static int	recurse = 0;
3855     list_T	*l;
3856     listitem_T	*li;
3857     dict_T	*d;
3858     hashitem_T	*hi;
3859     int		todo;
3860 
3861     if (recurse >= DICT_MAXNEST)
3862     {
3863 	EMSG(_("E743: variable nested too deep for (un)lock"));
3864 	return;
3865     }
3866     if (deep == 0)
3867 	return;
3868     ++recurse;
3869 
3870     /* lock/unlock the item itself */
3871     if (lock)
3872 	tv->v_lock |= VAR_LOCKED;
3873     else
3874 	tv->v_lock &= ~VAR_LOCKED;
3875 
3876     switch (tv->v_type)
3877     {
3878 	case VAR_UNKNOWN:
3879 	case VAR_NUMBER:
3880 	case VAR_STRING:
3881 	case VAR_FUNC:
3882 	case VAR_PARTIAL:
3883 	case VAR_FLOAT:
3884 	case VAR_SPECIAL:
3885 	case VAR_JOB:
3886 	case VAR_CHANNEL:
3887 	    break;
3888 
3889 	case VAR_LIST:
3890 	    if ((l = tv->vval.v_list) != NULL)
3891 	    {
3892 		if (lock)
3893 		    l->lv_lock |= VAR_LOCKED;
3894 		else
3895 		    l->lv_lock &= ~VAR_LOCKED;
3896 		if (deep < 0 || deep > 1)
3897 		    /* recursive: lock/unlock the items the List contains */
3898 		    for (li = l->lv_first; li != NULL; li = li->li_next)
3899 			item_lock(&li->li_tv, deep - 1, lock);
3900 	    }
3901 	    break;
3902 	case VAR_DICT:
3903 	    if ((d = tv->vval.v_dict) != NULL)
3904 	    {
3905 		if (lock)
3906 		    d->dv_lock |= VAR_LOCKED;
3907 		else
3908 		    d->dv_lock &= ~VAR_LOCKED;
3909 		if (deep < 0 || deep > 1)
3910 		{
3911 		    /* recursive: lock/unlock the items the List contains */
3912 		    todo = (int)d->dv_hashtab.ht_used;
3913 		    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
3914 		    {
3915 			if (!HASHITEM_EMPTY(hi))
3916 			{
3917 			    --todo;
3918 			    item_lock(&HI2DI(hi)->di_tv, deep - 1, lock);
3919 			}
3920 		    }
3921 		}
3922 	    }
3923     }
3924     --recurse;
3925 }
3926 
3927 /*
3928  * Return TRUE if typeval "tv" is locked: Either that value is locked itself
3929  * or it refers to a List or Dictionary that is locked.
3930  */
3931     static int
3932 tv_islocked(typval_T *tv)
3933 {
3934     return (tv->v_lock & VAR_LOCKED)
3935 	|| (tv->v_type == VAR_LIST
3936 		&& tv->vval.v_list != NULL
3937 		&& (tv->vval.v_list->lv_lock & VAR_LOCKED))
3938 	|| (tv->v_type == VAR_DICT
3939 		&& tv->vval.v_dict != NULL
3940 		&& (tv->vval.v_dict->dv_lock & VAR_LOCKED));
3941 }
3942 
3943 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO)
3944 /*
3945  * Delete all "menutrans_" variables.
3946  */
3947     void
3948 del_menutrans_vars(void)
3949 {
3950     hashitem_T	*hi;
3951     int		todo;
3952 
3953     hash_lock(&globvarht);
3954     todo = (int)globvarht.ht_used;
3955     for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi)
3956     {
3957 	if (!HASHITEM_EMPTY(hi))
3958 	{
3959 	    --todo;
3960 	    if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0)
3961 		delete_var(&globvarht, hi);
3962 	}
3963     }
3964     hash_unlock(&globvarht);
3965 }
3966 #endif
3967 
3968 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
3969 
3970 /*
3971  * Local string buffer for the next two functions to store a variable name
3972  * with its prefix. Allocated in cat_prefix_varname(), freed later in
3973  * get_user_var_name().
3974  */
3975 
3976 static char_u *cat_prefix_varname(int prefix, char_u *name);
3977 
3978 static char_u	*varnamebuf = NULL;
3979 static int	varnamebuflen = 0;
3980 
3981 /*
3982  * Function to concatenate a prefix and a variable name.
3983  */
3984     static char_u *
3985 cat_prefix_varname(int prefix, char_u *name)
3986 {
3987     int		len;
3988 
3989     len = (int)STRLEN(name) + 3;
3990     if (len > varnamebuflen)
3991     {
3992 	vim_free(varnamebuf);
3993 	len += 10;			/* some additional space */
3994 	varnamebuf = alloc(len);
3995 	if (varnamebuf == NULL)
3996 	{
3997 	    varnamebuflen = 0;
3998 	    return NULL;
3999 	}
4000 	varnamebuflen = len;
4001     }
4002     *varnamebuf = prefix;
4003     varnamebuf[1] = ':';
4004     STRCPY(varnamebuf + 2, name);
4005     return varnamebuf;
4006 }
4007 
4008 /*
4009  * Function given to ExpandGeneric() to obtain the list of user defined
4010  * (global/buffer/window/built-in) variable names.
4011  */
4012     char_u *
4013 get_user_var_name(expand_T *xp, int idx)
4014 {
4015     static long_u	gdone;
4016     static long_u	bdone;
4017     static long_u	wdone;
4018 #ifdef FEAT_WINDOWS
4019     static long_u	tdone;
4020 #endif
4021     static int		vidx;
4022     static hashitem_T	*hi;
4023     hashtab_T		*ht;
4024 
4025     if (idx == 0)
4026     {
4027 	gdone = bdone = wdone = vidx = 0;
4028 #ifdef FEAT_WINDOWS
4029 	tdone = 0;
4030 #endif
4031     }
4032 
4033     /* Global variables */
4034     if (gdone < globvarht.ht_used)
4035     {
4036 	if (gdone++ == 0)
4037 	    hi = globvarht.ht_array;
4038 	else
4039 	    ++hi;
4040 	while (HASHITEM_EMPTY(hi))
4041 	    ++hi;
4042 	if (STRNCMP("g:", xp->xp_pattern, 2) == 0)
4043 	    return cat_prefix_varname('g', hi->hi_key);
4044 	return hi->hi_key;
4045     }
4046 
4047     /* b: variables */
4048     ht = &curbuf->b_vars->dv_hashtab;
4049     if (bdone < ht->ht_used)
4050     {
4051 	if (bdone++ == 0)
4052 	    hi = ht->ht_array;
4053 	else
4054 	    ++hi;
4055 	while (HASHITEM_EMPTY(hi))
4056 	    ++hi;
4057 	return cat_prefix_varname('b', hi->hi_key);
4058     }
4059     if (bdone == ht->ht_used)
4060     {
4061 	++bdone;
4062 	return (char_u *)"b:changedtick";
4063     }
4064 
4065     /* w: variables */
4066     ht = &curwin->w_vars->dv_hashtab;
4067     if (wdone < ht->ht_used)
4068     {
4069 	if (wdone++ == 0)
4070 	    hi = ht->ht_array;
4071 	else
4072 	    ++hi;
4073 	while (HASHITEM_EMPTY(hi))
4074 	    ++hi;
4075 	return cat_prefix_varname('w', hi->hi_key);
4076     }
4077 
4078 #ifdef FEAT_WINDOWS
4079     /* t: variables */
4080     ht = &curtab->tp_vars->dv_hashtab;
4081     if (tdone < ht->ht_used)
4082     {
4083 	if (tdone++ == 0)
4084 	    hi = ht->ht_array;
4085 	else
4086 	    ++hi;
4087 	while (HASHITEM_EMPTY(hi))
4088 	    ++hi;
4089 	return cat_prefix_varname('t', hi->hi_key);
4090     }
4091 #endif
4092 
4093     /* v: variables */
4094     if (vidx < VV_LEN)
4095 	return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name);
4096 
4097     vim_free(varnamebuf);
4098     varnamebuf = NULL;
4099     varnamebuflen = 0;
4100     return NULL;
4101 }
4102 
4103 #endif /* FEAT_CMDL_COMPL */
4104 
4105 /*
4106  * types for expressions.
4107  */
4108 typedef enum
4109 {
4110     TYPE_UNKNOWN = 0
4111     , TYPE_EQUAL	/* == */
4112     , TYPE_NEQUAL	/* != */
4113     , TYPE_GREATER	/* >  */
4114     , TYPE_GEQUAL	/* >= */
4115     , TYPE_SMALLER	/* <  */
4116     , TYPE_SEQUAL	/* <= */
4117     , TYPE_MATCH	/* =~ */
4118     , TYPE_NOMATCH	/* !~ */
4119 } exptype_T;
4120 
4121 /*
4122  * The "evaluate" argument: When FALSE, the argument is only parsed but not
4123  * executed.  The function may return OK, but the rettv will be of type
4124  * VAR_UNKNOWN.  The function still returns FAIL for a syntax error.
4125  */
4126 
4127 /*
4128  * Handle zero level expression.
4129  * This calls eval1() and handles error message and nextcmd.
4130  * Put the result in "rettv" when returning OK and "evaluate" is TRUE.
4131  * Note: "rettv.v_lock" is not set.
4132  * Return OK or FAIL.
4133  */
4134     static int
4135 eval0(
4136     char_u	*arg,
4137     typval_T	*rettv,
4138     char_u	**nextcmd,
4139     int		evaluate)
4140 {
4141     int		ret;
4142     char_u	*p;
4143 
4144     p = skipwhite(arg);
4145     ret = eval1(&p, rettv, evaluate);
4146     if (ret == FAIL || !ends_excmd(*p))
4147     {
4148 	if (ret != FAIL)
4149 	    clear_tv(rettv);
4150 	/*
4151 	 * Report the invalid expression unless the expression evaluation has
4152 	 * been cancelled due to an aborting error, an interrupt, or an
4153 	 * exception.
4154 	 */
4155 	if (!aborting())
4156 	    EMSG2(_(e_invexpr2), arg);
4157 	ret = FAIL;
4158     }
4159     if (nextcmd != NULL)
4160 	*nextcmd = check_nextcmd(p);
4161 
4162     return ret;
4163 }
4164 
4165 /*
4166  * Handle top level expression:
4167  *	expr2 ? expr1 : expr1
4168  *
4169  * "arg" must point to the first non-white of the expression.
4170  * "arg" is advanced to the next non-white after the recognized expression.
4171  *
4172  * Note: "rettv.v_lock" is not set.
4173  *
4174  * Return OK or FAIL.
4175  */
4176     static int
4177 eval1(char_u **arg, typval_T *rettv, int evaluate)
4178 {
4179     int		result;
4180     typval_T	var2;
4181 
4182     /*
4183      * Get the first variable.
4184      */
4185     if (eval2(arg, rettv, evaluate) == FAIL)
4186 	return FAIL;
4187 
4188     if ((*arg)[0] == '?')
4189     {
4190 	result = FALSE;
4191 	if (evaluate)
4192 	{
4193 	    int		error = FALSE;
4194 
4195 	    if (get_tv_number_chk(rettv, &error) != 0)
4196 		result = TRUE;
4197 	    clear_tv(rettv);
4198 	    if (error)
4199 		return FAIL;
4200 	}
4201 
4202 	/*
4203 	 * Get the second variable.
4204 	 */
4205 	*arg = skipwhite(*arg + 1);
4206 	if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */
4207 	    return FAIL;
4208 
4209 	/*
4210 	 * Check for the ":".
4211 	 */
4212 	if ((*arg)[0] != ':')
4213 	{
4214 	    EMSG(_("E109: Missing ':' after '?'"));
4215 	    if (evaluate && result)
4216 		clear_tv(rettv);
4217 	    return FAIL;
4218 	}
4219 
4220 	/*
4221 	 * Get the third variable.
4222 	 */
4223 	*arg = skipwhite(*arg + 1);
4224 	if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */
4225 	{
4226 	    if (evaluate && result)
4227 		clear_tv(rettv);
4228 	    return FAIL;
4229 	}
4230 	if (evaluate && !result)
4231 	    *rettv = var2;
4232     }
4233 
4234     return OK;
4235 }
4236 
4237 /*
4238  * Handle first level expression:
4239  *	expr2 || expr2 || expr2	    logical OR
4240  *
4241  * "arg" must point to the first non-white of the expression.
4242  * "arg" is advanced to the next non-white after the recognized expression.
4243  *
4244  * Return OK or FAIL.
4245  */
4246     static int
4247 eval2(char_u **arg, typval_T *rettv, int evaluate)
4248 {
4249     typval_T	var2;
4250     long	result;
4251     int		first;
4252     int		error = FALSE;
4253 
4254     /*
4255      * Get the first variable.
4256      */
4257     if (eval3(arg, rettv, evaluate) == FAIL)
4258 	return FAIL;
4259 
4260     /*
4261      * Repeat until there is no following "||".
4262      */
4263     first = TRUE;
4264     result = FALSE;
4265     while ((*arg)[0] == '|' && (*arg)[1] == '|')
4266     {
4267 	if (evaluate && first)
4268 	{
4269 	    if (get_tv_number_chk(rettv, &error) != 0)
4270 		result = TRUE;
4271 	    clear_tv(rettv);
4272 	    if (error)
4273 		return FAIL;
4274 	    first = FALSE;
4275 	}
4276 
4277 	/*
4278 	 * Get the second variable.
4279 	 */
4280 	*arg = skipwhite(*arg + 2);
4281 	if (eval3(arg, &var2, evaluate && !result) == FAIL)
4282 	    return FAIL;
4283 
4284 	/*
4285 	 * Compute the result.
4286 	 */
4287 	if (evaluate && !result)
4288 	{
4289 	    if (get_tv_number_chk(&var2, &error) != 0)
4290 		result = TRUE;
4291 	    clear_tv(&var2);
4292 	    if (error)
4293 		return FAIL;
4294 	}
4295 	if (evaluate)
4296 	{
4297 	    rettv->v_type = VAR_NUMBER;
4298 	    rettv->vval.v_number = result;
4299 	}
4300     }
4301 
4302     return OK;
4303 }
4304 
4305 /*
4306  * Handle second level expression:
4307  *	expr3 && expr3 && expr3	    logical AND
4308  *
4309  * "arg" must point to the first non-white of the expression.
4310  * "arg" is advanced to the next non-white after the recognized expression.
4311  *
4312  * Return OK or FAIL.
4313  */
4314     static int
4315 eval3(char_u **arg, typval_T *rettv, int evaluate)
4316 {
4317     typval_T	var2;
4318     long	result;
4319     int		first;
4320     int		error = FALSE;
4321 
4322     /*
4323      * Get the first variable.
4324      */
4325     if (eval4(arg, rettv, evaluate) == FAIL)
4326 	return FAIL;
4327 
4328     /*
4329      * Repeat until there is no following "&&".
4330      */
4331     first = TRUE;
4332     result = TRUE;
4333     while ((*arg)[0] == '&' && (*arg)[1] == '&')
4334     {
4335 	if (evaluate && first)
4336 	{
4337 	    if (get_tv_number_chk(rettv, &error) == 0)
4338 		result = FALSE;
4339 	    clear_tv(rettv);
4340 	    if (error)
4341 		return FAIL;
4342 	    first = FALSE;
4343 	}
4344 
4345 	/*
4346 	 * Get the second variable.
4347 	 */
4348 	*arg = skipwhite(*arg + 2);
4349 	if (eval4(arg, &var2, evaluate && result) == FAIL)
4350 	    return FAIL;
4351 
4352 	/*
4353 	 * Compute the result.
4354 	 */
4355 	if (evaluate && result)
4356 	{
4357 	    if (get_tv_number_chk(&var2, &error) == 0)
4358 		result = FALSE;
4359 	    clear_tv(&var2);
4360 	    if (error)
4361 		return FAIL;
4362 	}
4363 	if (evaluate)
4364 	{
4365 	    rettv->v_type = VAR_NUMBER;
4366 	    rettv->vval.v_number = result;
4367 	}
4368     }
4369 
4370     return OK;
4371 }
4372 
4373 /*
4374  * Handle third level expression:
4375  *	var1 == var2
4376  *	var1 =~ var2
4377  *	var1 != var2
4378  *	var1 !~ var2
4379  *	var1 > var2
4380  *	var1 >= var2
4381  *	var1 < var2
4382  *	var1 <= var2
4383  *	var1 is var2
4384  *	var1 isnot var2
4385  *
4386  * "arg" must point to the first non-white of the expression.
4387  * "arg" is advanced to the next non-white after the recognized expression.
4388  *
4389  * Return OK or FAIL.
4390  */
4391     static int
4392 eval4(char_u **arg, typval_T *rettv, int evaluate)
4393 {
4394     typval_T	var2;
4395     char_u	*p;
4396     int		i;
4397     exptype_T	type = TYPE_UNKNOWN;
4398     int		type_is = FALSE;    /* TRUE for "is" and "isnot" */
4399     int		len = 2;
4400     long	n1, n2;
4401     char_u	*s1, *s2;
4402     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
4403     regmatch_T	regmatch;
4404     int		ic;
4405     char_u	*save_cpo;
4406 
4407     /*
4408      * Get the first variable.
4409      */
4410     if (eval5(arg, rettv, evaluate) == FAIL)
4411 	return FAIL;
4412 
4413     p = *arg;
4414     switch (p[0])
4415     {
4416 	case '=':   if (p[1] == '=')
4417 			type = TYPE_EQUAL;
4418 		    else if (p[1] == '~')
4419 			type = TYPE_MATCH;
4420 		    break;
4421 	case '!':   if (p[1] == '=')
4422 			type = TYPE_NEQUAL;
4423 		    else if (p[1] == '~')
4424 			type = TYPE_NOMATCH;
4425 		    break;
4426 	case '>':   if (p[1] != '=')
4427 		    {
4428 			type = TYPE_GREATER;
4429 			len = 1;
4430 		    }
4431 		    else
4432 			type = TYPE_GEQUAL;
4433 		    break;
4434 	case '<':   if (p[1] != '=')
4435 		    {
4436 			type = TYPE_SMALLER;
4437 			len = 1;
4438 		    }
4439 		    else
4440 			type = TYPE_SEQUAL;
4441 		    break;
4442 	case 'i':   if (p[1] == 's')
4443 		    {
4444 			if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
4445 			    len = 5;
4446 			i = p[len];
4447 			if (!isalnum(i) && i != '_')
4448 			{
4449 			    type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL;
4450 			    type_is = TRUE;
4451 			}
4452 		    }
4453 		    break;
4454     }
4455 
4456     /*
4457      * If there is a comparative operator, use it.
4458      */
4459     if (type != TYPE_UNKNOWN)
4460     {
4461 	/* extra question mark appended: ignore case */
4462 	if (p[len] == '?')
4463 	{
4464 	    ic = TRUE;
4465 	    ++len;
4466 	}
4467 	/* extra '#' appended: match case */
4468 	else if (p[len] == '#')
4469 	{
4470 	    ic = FALSE;
4471 	    ++len;
4472 	}
4473 	/* nothing appended: use 'ignorecase' */
4474 	else
4475 	    ic = p_ic;
4476 
4477 	/*
4478 	 * Get the second variable.
4479 	 */
4480 	*arg = skipwhite(p + len);
4481 	if (eval5(arg, &var2, evaluate) == FAIL)
4482 	{
4483 	    clear_tv(rettv);
4484 	    return FAIL;
4485 	}
4486 
4487 	if (evaluate)
4488 	{
4489 	    if (type_is && rettv->v_type != var2.v_type)
4490 	    {
4491 		/* For "is" a different type always means FALSE, for "notis"
4492 		 * it means TRUE. */
4493 		n1 = (type == TYPE_NEQUAL);
4494 	    }
4495 	    else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST)
4496 	    {
4497 		if (type_is)
4498 		{
4499 		    n1 = (rettv->v_type == var2.v_type
4500 				   && rettv->vval.v_list == var2.vval.v_list);
4501 		    if (type == TYPE_NEQUAL)
4502 			n1 = !n1;
4503 		}
4504 		else if (rettv->v_type != var2.v_type
4505 			|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
4506 		{
4507 		    if (rettv->v_type != var2.v_type)
4508 			EMSG(_("E691: Can only compare List with List"));
4509 		    else
4510 			EMSG(_("E692: Invalid operation for List"));
4511 		    clear_tv(rettv);
4512 		    clear_tv(&var2);
4513 		    return FAIL;
4514 		}
4515 		else
4516 		{
4517 		    /* Compare two Lists for being equal or unequal. */
4518 		    n1 = list_equal(rettv->vval.v_list, var2.vval.v_list,
4519 								   ic, FALSE);
4520 		    if (type == TYPE_NEQUAL)
4521 			n1 = !n1;
4522 		}
4523 	    }
4524 
4525 	    else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT)
4526 	    {
4527 		if (type_is)
4528 		{
4529 		    n1 = (rettv->v_type == var2.v_type
4530 				   && rettv->vval.v_dict == var2.vval.v_dict);
4531 		    if (type == TYPE_NEQUAL)
4532 			n1 = !n1;
4533 		}
4534 		else if (rettv->v_type != var2.v_type
4535 			|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
4536 		{
4537 		    if (rettv->v_type != var2.v_type)
4538 			EMSG(_("E735: Can only compare Dictionary with Dictionary"));
4539 		    else
4540 			EMSG(_("E736: Invalid operation for Dictionary"));
4541 		    clear_tv(rettv);
4542 		    clear_tv(&var2);
4543 		    return FAIL;
4544 		}
4545 		else
4546 		{
4547 		    /* Compare two Dictionaries for being equal or unequal. */
4548 		    n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict,
4549 								   ic, FALSE);
4550 		    if (type == TYPE_NEQUAL)
4551 			n1 = !n1;
4552 		}
4553 	    }
4554 
4555 	    else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC
4556 		|| rettv->v_type == VAR_PARTIAL || var2.v_type == VAR_PARTIAL)
4557 	    {
4558 		if (type != TYPE_EQUAL && type != TYPE_NEQUAL)
4559 		{
4560 		    EMSG(_("E694: Invalid operation for Funcrefs"));
4561 		    clear_tv(rettv);
4562 		    clear_tv(&var2);
4563 		    return FAIL;
4564 		}
4565 		n1 = tv_equal(rettv, &var2, FALSE, FALSE);
4566 		if (type == TYPE_NEQUAL)
4567 		    n1 = !n1;
4568 	    }
4569 
4570 #ifdef FEAT_FLOAT
4571 	    /*
4572 	     * If one of the two variables is a float, compare as a float.
4573 	     * When using "=~" or "!~", always compare as string.
4574 	     */
4575 	    else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
4576 		    && type != TYPE_MATCH && type != TYPE_NOMATCH)
4577 	    {
4578 		float_T f1, f2;
4579 
4580 		if (rettv->v_type == VAR_FLOAT)
4581 		    f1 = rettv->vval.v_float;
4582 		else
4583 		    f1 = get_tv_number(rettv);
4584 		if (var2.v_type == VAR_FLOAT)
4585 		    f2 = var2.vval.v_float;
4586 		else
4587 		    f2 = get_tv_number(&var2);
4588 		n1 = FALSE;
4589 		switch (type)
4590 		{
4591 		    case TYPE_EQUAL:    n1 = (f1 == f2); break;
4592 		    case TYPE_NEQUAL:   n1 = (f1 != f2); break;
4593 		    case TYPE_GREATER:  n1 = (f1 > f2); break;
4594 		    case TYPE_GEQUAL:   n1 = (f1 >= f2); break;
4595 		    case TYPE_SMALLER:  n1 = (f1 < f2); break;
4596 		    case TYPE_SEQUAL:   n1 = (f1 <= f2); break;
4597 		    case TYPE_UNKNOWN:
4598 		    case TYPE_MATCH:
4599 		    case TYPE_NOMATCH:  break;  /* avoid gcc warning */
4600 		}
4601 	    }
4602 #endif
4603 
4604 	    /*
4605 	     * If one of the two variables is a number, compare as a number.
4606 	     * When using "=~" or "!~", always compare as string.
4607 	     */
4608 	    else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER)
4609 		    && type != TYPE_MATCH && type != TYPE_NOMATCH)
4610 	    {
4611 		n1 = get_tv_number(rettv);
4612 		n2 = get_tv_number(&var2);
4613 		switch (type)
4614 		{
4615 		    case TYPE_EQUAL:    n1 = (n1 == n2); break;
4616 		    case TYPE_NEQUAL:   n1 = (n1 != n2); break;
4617 		    case TYPE_GREATER:  n1 = (n1 > n2); break;
4618 		    case TYPE_GEQUAL:   n1 = (n1 >= n2); break;
4619 		    case TYPE_SMALLER:  n1 = (n1 < n2); break;
4620 		    case TYPE_SEQUAL:   n1 = (n1 <= n2); break;
4621 		    case TYPE_UNKNOWN:
4622 		    case TYPE_MATCH:
4623 		    case TYPE_NOMATCH:  break;  /* avoid gcc warning */
4624 		}
4625 	    }
4626 	    else
4627 	    {
4628 		s1 = get_tv_string_buf(rettv, buf1);
4629 		s2 = get_tv_string_buf(&var2, buf2);
4630 		if (type != TYPE_MATCH && type != TYPE_NOMATCH)
4631 		    i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
4632 		else
4633 		    i = 0;
4634 		n1 = FALSE;
4635 		switch (type)
4636 		{
4637 		    case TYPE_EQUAL:    n1 = (i == 0); break;
4638 		    case TYPE_NEQUAL:   n1 = (i != 0); break;
4639 		    case TYPE_GREATER:  n1 = (i > 0); break;
4640 		    case TYPE_GEQUAL:   n1 = (i >= 0); break;
4641 		    case TYPE_SMALLER:  n1 = (i < 0); break;
4642 		    case TYPE_SEQUAL:   n1 = (i <= 0); break;
4643 
4644 		    case TYPE_MATCH:
4645 		    case TYPE_NOMATCH:
4646 			    /* avoid 'l' flag in 'cpoptions' */
4647 			    save_cpo = p_cpo;
4648 			    p_cpo = (char_u *)"";
4649 			    regmatch.regprog = vim_regcomp(s2,
4650 							RE_MAGIC + RE_STRING);
4651 			    regmatch.rm_ic = ic;
4652 			    if (regmatch.regprog != NULL)
4653 			    {
4654 				n1 = vim_regexec_nl(&regmatch, s1, (colnr_T)0);
4655 				vim_regfree(regmatch.regprog);
4656 				if (type == TYPE_NOMATCH)
4657 				    n1 = !n1;
4658 			    }
4659 			    p_cpo = save_cpo;
4660 			    break;
4661 
4662 		    case TYPE_UNKNOWN:  break;  /* avoid gcc warning */
4663 		}
4664 	    }
4665 	    clear_tv(rettv);
4666 	    clear_tv(&var2);
4667 	    rettv->v_type = VAR_NUMBER;
4668 	    rettv->vval.v_number = n1;
4669 	}
4670     }
4671 
4672     return OK;
4673 }
4674 
4675 /*
4676  * Handle fourth level expression:
4677  *	+	number addition
4678  *	-	number subtraction
4679  *	.	string concatenation
4680  *
4681  * "arg" must point to the first non-white of the expression.
4682  * "arg" is advanced to the next non-white after the recognized expression.
4683  *
4684  * Return OK or FAIL.
4685  */
4686     static int
4687 eval5(char_u **arg, typval_T *rettv, int evaluate)
4688 {
4689     typval_T	var2;
4690     typval_T	var3;
4691     int		op;
4692     long	n1, n2;
4693 #ifdef FEAT_FLOAT
4694     float_T	f1 = 0, f2 = 0;
4695 #endif
4696     char_u	*s1, *s2;
4697     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
4698     char_u	*p;
4699 
4700     /*
4701      * Get the first variable.
4702      */
4703     if (eval6(arg, rettv, evaluate, FALSE) == FAIL)
4704 	return FAIL;
4705 
4706     /*
4707      * Repeat computing, until no '+', '-' or '.' is following.
4708      */
4709     for (;;)
4710     {
4711 	op = **arg;
4712 	if (op != '+' && op != '-' && op != '.')
4713 	    break;
4714 
4715 	if ((op != '+' || rettv->v_type != VAR_LIST)
4716 #ifdef FEAT_FLOAT
4717 		&& (op == '.' || rettv->v_type != VAR_FLOAT)
4718 #endif
4719 		)
4720 	{
4721 	    /* For "list + ...", an illegal use of the first operand as
4722 	     * a number cannot be determined before evaluating the 2nd
4723 	     * operand: if this is also a list, all is ok.
4724 	     * For "something . ...", "something - ..." or "non-list + ...",
4725 	     * we know that the first operand needs to be a string or number
4726 	     * without evaluating the 2nd operand.  So check before to avoid
4727 	     * side effects after an error. */
4728 	    if (evaluate && get_tv_string_chk(rettv) == NULL)
4729 	    {
4730 		clear_tv(rettv);
4731 		return FAIL;
4732 	    }
4733 	}
4734 
4735 	/*
4736 	 * Get the second variable.
4737 	 */
4738 	*arg = skipwhite(*arg + 1);
4739 	if (eval6(arg, &var2, evaluate, op == '.') == FAIL)
4740 	{
4741 	    clear_tv(rettv);
4742 	    return FAIL;
4743 	}
4744 
4745 	if (evaluate)
4746 	{
4747 	    /*
4748 	     * Compute the result.
4749 	     */
4750 	    if (op == '.')
4751 	    {
4752 		s1 = get_tv_string_buf(rettv, buf1);	/* already checked */
4753 		s2 = get_tv_string_buf_chk(&var2, buf2);
4754 		if (s2 == NULL)		/* type error ? */
4755 		{
4756 		    clear_tv(rettv);
4757 		    clear_tv(&var2);
4758 		    return FAIL;
4759 		}
4760 		p = concat_str(s1, s2);
4761 		clear_tv(rettv);
4762 		rettv->v_type = VAR_STRING;
4763 		rettv->vval.v_string = p;
4764 	    }
4765 	    else if (op == '+' && rettv->v_type == VAR_LIST
4766 						   && var2.v_type == VAR_LIST)
4767 	    {
4768 		/* concatenate Lists */
4769 		if (list_concat(rettv->vval.v_list, var2.vval.v_list,
4770 							       &var3) == FAIL)
4771 		{
4772 		    clear_tv(rettv);
4773 		    clear_tv(&var2);
4774 		    return FAIL;
4775 		}
4776 		clear_tv(rettv);
4777 		*rettv = var3;
4778 	    }
4779 	    else
4780 	    {
4781 		int	    error = FALSE;
4782 
4783 #ifdef FEAT_FLOAT
4784 		if (rettv->v_type == VAR_FLOAT)
4785 		{
4786 		    f1 = rettv->vval.v_float;
4787 		    n1 = 0;
4788 		}
4789 		else
4790 #endif
4791 		{
4792 		    n1 = get_tv_number_chk(rettv, &error);
4793 		    if (error)
4794 		    {
4795 			/* This can only happen for "list + non-list".  For
4796 			 * "non-list + ..." or "something - ...", we returned
4797 			 * before evaluating the 2nd operand. */
4798 			clear_tv(rettv);
4799 			return FAIL;
4800 		    }
4801 #ifdef FEAT_FLOAT
4802 		    if (var2.v_type == VAR_FLOAT)
4803 			f1 = n1;
4804 #endif
4805 		}
4806 #ifdef FEAT_FLOAT
4807 		if (var2.v_type == VAR_FLOAT)
4808 		{
4809 		    f2 = var2.vval.v_float;
4810 		    n2 = 0;
4811 		}
4812 		else
4813 #endif
4814 		{
4815 		    n2 = get_tv_number_chk(&var2, &error);
4816 		    if (error)
4817 		    {
4818 			clear_tv(rettv);
4819 			clear_tv(&var2);
4820 			return FAIL;
4821 		    }
4822 #ifdef FEAT_FLOAT
4823 		    if (rettv->v_type == VAR_FLOAT)
4824 			f2 = n2;
4825 #endif
4826 		}
4827 		clear_tv(rettv);
4828 
4829 #ifdef FEAT_FLOAT
4830 		/* If there is a float on either side the result is a float. */
4831 		if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
4832 		{
4833 		    if (op == '+')
4834 			f1 = f1 + f2;
4835 		    else
4836 			f1 = f1 - f2;
4837 		    rettv->v_type = VAR_FLOAT;
4838 		    rettv->vval.v_float = f1;
4839 		}
4840 		else
4841 #endif
4842 		{
4843 		    if (op == '+')
4844 			n1 = n1 + n2;
4845 		    else
4846 			n1 = n1 - n2;
4847 		    rettv->v_type = VAR_NUMBER;
4848 		    rettv->vval.v_number = n1;
4849 		}
4850 	    }
4851 	    clear_tv(&var2);
4852 	}
4853     }
4854     return OK;
4855 }
4856 
4857 /*
4858  * Handle fifth level expression:
4859  *	*	number multiplication
4860  *	/	number division
4861  *	%	number modulo
4862  *
4863  * "arg" must point to the first non-white of the expression.
4864  * "arg" is advanced to the next non-white after the recognized expression.
4865  *
4866  * Return OK or FAIL.
4867  */
4868     static int
4869 eval6(
4870     char_u	**arg,
4871     typval_T	*rettv,
4872     int		evaluate,
4873     int		want_string)  /* after "." operator */
4874 {
4875     typval_T	var2;
4876     int		op;
4877     long	n1, n2;
4878 #ifdef FEAT_FLOAT
4879     int		use_float = FALSE;
4880     float_T	f1 = 0, f2;
4881 #endif
4882     int		error = FALSE;
4883 
4884     /*
4885      * Get the first variable.
4886      */
4887     if (eval7(arg, rettv, evaluate, want_string) == FAIL)
4888 	return FAIL;
4889 
4890     /*
4891      * Repeat computing, until no '*', '/' or '%' is following.
4892      */
4893     for (;;)
4894     {
4895 	op = **arg;
4896 	if (op != '*' && op != '/' && op != '%')
4897 	    break;
4898 
4899 	if (evaluate)
4900 	{
4901 #ifdef FEAT_FLOAT
4902 	    if (rettv->v_type == VAR_FLOAT)
4903 	    {
4904 		f1 = rettv->vval.v_float;
4905 		use_float = TRUE;
4906 		n1 = 0;
4907 	    }
4908 	    else
4909 #endif
4910 		n1 = get_tv_number_chk(rettv, &error);
4911 	    clear_tv(rettv);
4912 	    if (error)
4913 		return FAIL;
4914 	}
4915 	else
4916 	    n1 = 0;
4917 
4918 	/*
4919 	 * Get the second variable.
4920 	 */
4921 	*arg = skipwhite(*arg + 1);
4922 	if (eval7(arg, &var2, evaluate, FALSE) == FAIL)
4923 	    return FAIL;
4924 
4925 	if (evaluate)
4926 	{
4927 #ifdef FEAT_FLOAT
4928 	    if (var2.v_type == VAR_FLOAT)
4929 	    {
4930 		if (!use_float)
4931 		{
4932 		    f1 = n1;
4933 		    use_float = TRUE;
4934 		}
4935 		f2 = var2.vval.v_float;
4936 		n2 = 0;
4937 	    }
4938 	    else
4939 #endif
4940 	    {
4941 		n2 = get_tv_number_chk(&var2, &error);
4942 		clear_tv(&var2);
4943 		if (error)
4944 		    return FAIL;
4945 #ifdef FEAT_FLOAT
4946 		if (use_float)
4947 		    f2 = n2;
4948 #endif
4949 	    }
4950 
4951 	    /*
4952 	     * Compute the result.
4953 	     * When either side is a float the result is a float.
4954 	     */
4955 #ifdef FEAT_FLOAT
4956 	    if (use_float)
4957 	    {
4958 		if (op == '*')
4959 		    f1 = f1 * f2;
4960 		else if (op == '/')
4961 		{
4962 # ifdef VMS
4963 		    /* VMS crashes on divide by zero, work around it */
4964 		    if (f2 == 0.0)
4965 		    {
4966 			if (f1 == 0)
4967 			    f1 = -1 * __F_FLT_MAX - 1L;   /* similar to NaN */
4968 			else if (f1 < 0)
4969 			    f1 = -1 * __F_FLT_MAX;
4970 			else
4971 			    f1 = __F_FLT_MAX;
4972 		    }
4973 		    else
4974 			f1 = f1 / f2;
4975 # else
4976 		    /* We rely on the floating point library to handle divide
4977 		     * by zero to result in "inf" and not a crash. */
4978 		    f1 = f1 / f2;
4979 # endif
4980 		}
4981 		else
4982 		{
4983 		    EMSG(_("E804: Cannot use '%' with Float"));
4984 		    return FAIL;
4985 		}
4986 		rettv->v_type = VAR_FLOAT;
4987 		rettv->vval.v_float = f1;
4988 	    }
4989 	    else
4990 #endif
4991 	    {
4992 		if (op == '*')
4993 		    n1 = n1 * n2;
4994 		else if (op == '/')
4995 		{
4996 		    if (n2 == 0)	/* give an error message? */
4997 		    {
4998 			if (n1 == 0)
4999 			    n1 = -0x7fffffffL - 1L;	/* similar to NaN */
5000 			else if (n1 < 0)
5001 			    n1 = -0x7fffffffL;
5002 			else
5003 			    n1 = 0x7fffffffL;
5004 		    }
5005 		    else
5006 			n1 = n1 / n2;
5007 		}
5008 		else
5009 		{
5010 		    if (n2 == 0)	/* give an error message? */
5011 			n1 = 0;
5012 		    else
5013 			n1 = n1 % n2;
5014 		}
5015 		rettv->v_type = VAR_NUMBER;
5016 		rettv->vval.v_number = n1;
5017 	    }
5018 	}
5019     }
5020 
5021     return OK;
5022 }
5023 
5024 /*
5025  * Handle sixth level expression:
5026  *  number		number constant
5027  *  "string"		string constant
5028  *  'string'		literal string constant
5029  *  &option-name	option value
5030  *  @r			register contents
5031  *  identifier		variable value
5032  *  function()		function call
5033  *  $VAR		environment variable
5034  *  (expression)	nested expression
5035  *  [expr, expr]	List
5036  *  {key: val, key: val}  Dictionary
5037  *
5038  *  Also handle:
5039  *  ! in front		logical NOT
5040  *  - in front		unary minus
5041  *  + in front		unary plus (ignored)
5042  *  trailing []		subscript in String or List
5043  *  trailing .name	entry in Dictionary
5044  *
5045  * "arg" must point to the first non-white of the expression.
5046  * "arg" is advanced to the next non-white after the recognized expression.
5047  *
5048  * Return OK or FAIL.
5049  */
5050     static int
5051 eval7(
5052     char_u	**arg,
5053     typval_T	*rettv,
5054     int		evaluate,
5055     int		want_string UNUSED)	/* after "." operator */
5056 {
5057     long	n;
5058     int		len;
5059     char_u	*s;
5060     char_u	*start_leader, *end_leader;
5061     int		ret = OK;
5062     char_u	*alias;
5063 
5064     /*
5065      * Initialise variable so that clear_tv() can't mistake this for a
5066      * string and free a string that isn't there.
5067      */
5068     rettv->v_type = VAR_UNKNOWN;
5069 
5070     /*
5071      * Skip '!' and '-' characters.  They are handled later.
5072      */
5073     start_leader = *arg;
5074     while (**arg == '!' || **arg == '-' || **arg == '+')
5075 	*arg = skipwhite(*arg + 1);
5076     end_leader = *arg;
5077 
5078     switch (**arg)
5079     {
5080     /*
5081      * Number constant.
5082      */
5083     case '0':
5084     case '1':
5085     case '2':
5086     case '3':
5087     case '4':
5088     case '5':
5089     case '6':
5090     case '7':
5091     case '8':
5092     case '9':
5093 	{
5094 #ifdef FEAT_FLOAT
5095 		char_u *p = skipdigits(*arg + 1);
5096 		int    get_float = FALSE;
5097 
5098 		/* We accept a float when the format matches
5099 		 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?".  This is very
5100 		 * strict to avoid backwards compatibility problems.
5101 		 * Don't look for a float after the "." operator, so that
5102 		 * ":let vers = 1.2.3" doesn't fail. */
5103 		if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
5104 		{
5105 		    get_float = TRUE;
5106 		    p = skipdigits(p + 2);
5107 		    if (*p == 'e' || *p == 'E')
5108 		    {
5109 			++p;
5110 			if (*p == '-' || *p == '+')
5111 			    ++p;
5112 			if (!vim_isdigit(*p))
5113 			    get_float = FALSE;
5114 			else
5115 			    p = skipdigits(p + 1);
5116 		    }
5117 		    if (ASCII_ISALPHA(*p) || *p == '.')
5118 			get_float = FALSE;
5119 		}
5120 		if (get_float)
5121 		{
5122 		    float_T	f;
5123 
5124 		    *arg += string2float(*arg, &f);
5125 		    if (evaluate)
5126 		    {
5127 			rettv->v_type = VAR_FLOAT;
5128 			rettv->vval.v_float = f;
5129 		    }
5130 		}
5131 		else
5132 #endif
5133 		{
5134 		    vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0);
5135 		    *arg += len;
5136 		    if (evaluate)
5137 		    {
5138 			rettv->v_type = VAR_NUMBER;
5139 			rettv->vval.v_number = n;
5140 		    }
5141 		}
5142 		break;
5143 	}
5144 
5145     /*
5146      * String constant: "string".
5147      */
5148     case '"':	ret = get_string_tv(arg, rettv, evaluate);
5149 		break;
5150 
5151     /*
5152      * Literal string constant: 'str''ing'.
5153      */
5154     case '\'':	ret = get_lit_string_tv(arg, rettv, evaluate);
5155 		break;
5156 
5157     /*
5158      * List: [expr, expr]
5159      */
5160     case '[':	ret = get_list_tv(arg, rettv, evaluate);
5161 		break;
5162 
5163     /*
5164      * Dictionary: {key: val, key: val}
5165      */
5166     case '{':	ret = get_dict_tv(arg, rettv, evaluate);
5167 		break;
5168 
5169     /*
5170      * Option value: &name
5171      */
5172     case '&':	ret = get_option_tv(arg, rettv, evaluate);
5173 		break;
5174 
5175     /*
5176      * Environment variable: $VAR.
5177      */
5178     case '$':	ret = get_env_tv(arg, rettv, evaluate);
5179 		break;
5180 
5181     /*
5182      * Register contents: @r.
5183      */
5184     case '@':	++*arg;
5185 		if (evaluate)
5186 		{
5187 		    rettv->v_type = VAR_STRING;
5188 		    rettv->vval.v_string = get_reg_contents(**arg,
5189 							    GREG_EXPR_SRC);
5190 		}
5191 		if (**arg != NUL)
5192 		    ++*arg;
5193 		break;
5194 
5195     /*
5196      * nested expression: (expression).
5197      */
5198     case '(':	*arg = skipwhite(*arg + 1);
5199 		ret = eval1(arg, rettv, evaluate);	/* recursive! */
5200 		if (**arg == ')')
5201 		    ++*arg;
5202 		else if (ret == OK)
5203 		{
5204 		    EMSG(_("E110: Missing ')'"));
5205 		    clear_tv(rettv);
5206 		    ret = FAIL;
5207 		}
5208 		break;
5209 
5210     default:	ret = NOTDONE;
5211 		break;
5212     }
5213 
5214     if (ret == NOTDONE)
5215     {
5216 	/*
5217 	 * Must be a variable or function name.
5218 	 * Can also be a curly-braces kind of name: {expr}.
5219 	 */
5220 	s = *arg;
5221 	len = get_name_len(arg, &alias, evaluate, TRUE);
5222 	if (alias != NULL)
5223 	    s = alias;
5224 
5225 	if (len <= 0)
5226 	    ret = FAIL;
5227 	else
5228 	{
5229 	    if (**arg == '(')		/* recursive! */
5230 	    {
5231 		partial_T *partial;
5232 
5233 		/* If "s" is the name of a variable of type VAR_FUNC
5234 		 * use its contents. */
5235 		s = deref_func_name(s, &len, &partial, !evaluate);
5236 
5237 		/* Invoke the function. */
5238 		ret = get_func_tv(s, len, rettv, arg,
5239 			  curwin->w_cursor.lnum, curwin->w_cursor.lnum,
5240 			  &len, evaluate, partial, NULL);
5241 
5242 		/* If evaluate is FALSE rettv->v_type was not set in
5243 		 * get_func_tv, but it's needed in handle_subscript() to parse
5244 		 * what follows. So set it here. */
5245 		if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(')
5246 		{
5247 		    rettv->vval.v_string = vim_strsave((char_u *)"");
5248 		    rettv->v_type = VAR_FUNC;
5249 		}
5250 
5251 		/* Stop the expression evaluation when immediately
5252 		 * aborting on error, or when an interrupt occurred or
5253 		 * an exception was thrown but not caught. */
5254 		if (aborting())
5255 		{
5256 		    if (ret == OK)
5257 			clear_tv(rettv);
5258 		    ret = FAIL;
5259 		}
5260 	    }
5261 	    else if (evaluate)
5262 		ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE);
5263 	    else
5264 		ret = OK;
5265 	}
5266 	vim_free(alias);
5267     }
5268 
5269     *arg = skipwhite(*arg);
5270 
5271     /* Handle following '[', '(' and '.' for expr[expr], expr.name,
5272      * expr(expr). */
5273     if (ret == OK)
5274 	ret = handle_subscript(arg, rettv, evaluate, TRUE);
5275 
5276     /*
5277      * Apply logical NOT and unary '-', from right to left, ignore '+'.
5278      */
5279     if (ret == OK && evaluate && end_leader > start_leader)
5280     {
5281 	int	    error = FALSE;
5282 	int	    val = 0;
5283 #ifdef FEAT_FLOAT
5284 	float_T	    f = 0.0;
5285 
5286 	if (rettv->v_type == VAR_FLOAT)
5287 	    f = rettv->vval.v_float;
5288 	else
5289 #endif
5290 	    val = get_tv_number_chk(rettv, &error);
5291 	if (error)
5292 	{
5293 	    clear_tv(rettv);
5294 	    ret = FAIL;
5295 	}
5296 	else
5297 	{
5298 	    while (end_leader > start_leader)
5299 	    {
5300 		--end_leader;
5301 		if (*end_leader == '!')
5302 		{
5303 #ifdef FEAT_FLOAT
5304 		    if (rettv->v_type == VAR_FLOAT)
5305 			f = !f;
5306 		    else
5307 #endif
5308 			val = !val;
5309 		}
5310 		else if (*end_leader == '-')
5311 		{
5312 #ifdef FEAT_FLOAT
5313 		    if (rettv->v_type == VAR_FLOAT)
5314 			f = -f;
5315 		    else
5316 #endif
5317 			val = -val;
5318 		}
5319 	    }
5320 #ifdef FEAT_FLOAT
5321 	    if (rettv->v_type == VAR_FLOAT)
5322 	    {
5323 		clear_tv(rettv);
5324 		rettv->vval.v_float = f;
5325 	    }
5326 	    else
5327 #endif
5328 	    {
5329 		clear_tv(rettv);
5330 		rettv->v_type = VAR_NUMBER;
5331 		rettv->vval.v_number = val;
5332 	    }
5333 	}
5334     }
5335 
5336     return ret;
5337 }
5338 
5339 /*
5340  * Evaluate an "[expr]" or "[expr:expr]" index.  Also "dict.key".
5341  * "*arg" points to the '[' or '.'.
5342  * Returns FAIL or OK. "*arg" is advanced to after the ']'.
5343  */
5344     static int
5345 eval_index(
5346     char_u	**arg,
5347     typval_T	*rettv,
5348     int		evaluate,
5349     int		verbose)	/* give error messages */
5350 {
5351     int		empty1 = FALSE, empty2 = FALSE;
5352     typval_T	var1, var2;
5353     long	n1, n2 = 0;
5354     long	len = -1;
5355     int		range = FALSE;
5356     char_u	*s;
5357     char_u	*key = NULL;
5358 
5359     switch (rettv->v_type)
5360     {
5361 	case VAR_FUNC:
5362 	case VAR_PARTIAL:
5363 	    if (verbose)
5364 		EMSG(_("E695: Cannot index a Funcref"));
5365 	    return FAIL;
5366 	case VAR_FLOAT:
5367 #ifdef FEAT_FLOAT
5368 	    if (verbose)
5369 		EMSG(_(e_float_as_string));
5370 	    return FAIL;
5371 #endif
5372 	case VAR_SPECIAL:
5373 	case VAR_JOB:
5374 	case VAR_CHANNEL:
5375 	    if (verbose)
5376 		EMSG(_("E909: Cannot index a special variable"));
5377 	    return FAIL;
5378 	case VAR_UNKNOWN:
5379 	    if (evaluate)
5380 		return FAIL;
5381 	    /* FALLTHROUGH */
5382 
5383 	case VAR_STRING:
5384 	case VAR_NUMBER:
5385 	case VAR_LIST:
5386 	case VAR_DICT:
5387 	    break;
5388     }
5389 
5390     init_tv(&var1);
5391     init_tv(&var2);
5392     if (**arg == '.')
5393     {
5394 	/*
5395 	 * dict.name
5396 	 */
5397 	key = *arg + 1;
5398 	for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
5399 	    ;
5400 	if (len == 0)
5401 	    return FAIL;
5402 	*arg = skipwhite(key + len);
5403     }
5404     else
5405     {
5406 	/*
5407 	 * something[idx]
5408 	 *
5409 	 * Get the (first) variable from inside the [].
5410 	 */
5411 	*arg = skipwhite(*arg + 1);
5412 	if (**arg == ':')
5413 	    empty1 = TRUE;
5414 	else if (eval1(arg, &var1, evaluate) == FAIL)	/* recursive! */
5415 	    return FAIL;
5416 	else if (evaluate && get_tv_string_chk(&var1) == NULL)
5417 	{
5418 	    /* not a number or string */
5419 	    clear_tv(&var1);
5420 	    return FAIL;
5421 	}
5422 
5423 	/*
5424 	 * Get the second variable from inside the [:].
5425 	 */
5426 	if (**arg == ':')
5427 	{
5428 	    range = TRUE;
5429 	    *arg = skipwhite(*arg + 1);
5430 	    if (**arg == ']')
5431 		empty2 = TRUE;
5432 	    else if (eval1(arg, &var2, evaluate) == FAIL)	/* recursive! */
5433 	    {
5434 		if (!empty1)
5435 		    clear_tv(&var1);
5436 		return FAIL;
5437 	    }
5438 	    else if (evaluate && get_tv_string_chk(&var2) == NULL)
5439 	    {
5440 		/* not a number or string */
5441 		if (!empty1)
5442 		    clear_tv(&var1);
5443 		clear_tv(&var2);
5444 		return FAIL;
5445 	    }
5446 	}
5447 
5448 	/* Check for the ']'. */
5449 	if (**arg != ']')
5450 	{
5451 	    if (verbose)
5452 		EMSG(_(e_missbrac));
5453 	    clear_tv(&var1);
5454 	    if (range)
5455 		clear_tv(&var2);
5456 	    return FAIL;
5457 	}
5458 	*arg = skipwhite(*arg + 1);	/* skip the ']' */
5459     }
5460 
5461     if (evaluate)
5462     {
5463 	n1 = 0;
5464 	if (!empty1 && rettv->v_type != VAR_DICT)
5465 	{
5466 	    n1 = get_tv_number(&var1);
5467 	    clear_tv(&var1);
5468 	}
5469 	if (range)
5470 	{
5471 	    if (empty2)
5472 		n2 = -1;
5473 	    else
5474 	    {
5475 		n2 = get_tv_number(&var2);
5476 		clear_tv(&var2);
5477 	    }
5478 	}
5479 
5480 	switch (rettv->v_type)
5481 	{
5482 	    case VAR_UNKNOWN:
5483 	    case VAR_FUNC:
5484 	    case VAR_PARTIAL:
5485 	    case VAR_FLOAT:
5486 	    case VAR_SPECIAL:
5487 	    case VAR_JOB:
5488 	    case VAR_CHANNEL:
5489 		break; /* not evaluating, skipping over subscript */
5490 
5491 	    case VAR_NUMBER:
5492 	    case VAR_STRING:
5493 		s = get_tv_string(rettv);
5494 		len = (long)STRLEN(s);
5495 		if (range)
5496 		{
5497 		    /* The resulting variable is a substring.  If the indexes
5498 		     * are out of range the result is empty. */
5499 		    if (n1 < 0)
5500 		    {
5501 			n1 = len + n1;
5502 			if (n1 < 0)
5503 			    n1 = 0;
5504 		    }
5505 		    if (n2 < 0)
5506 			n2 = len + n2;
5507 		    else if (n2 >= len)
5508 			n2 = len;
5509 		    if (n1 >= len || n2 < 0 || n1 > n2)
5510 			s = NULL;
5511 		    else
5512 			s = vim_strnsave(s + n1, (int)(n2 - n1 + 1));
5513 		}
5514 		else
5515 		{
5516 		    /* The resulting variable is a string of a single
5517 		     * character.  If the index is too big or negative the
5518 		     * result is empty. */
5519 		    if (n1 >= len || n1 < 0)
5520 			s = NULL;
5521 		    else
5522 			s = vim_strnsave(s + n1, 1);
5523 		}
5524 		clear_tv(rettv);
5525 		rettv->v_type = VAR_STRING;
5526 		rettv->vval.v_string = s;
5527 		break;
5528 
5529 	    case VAR_LIST:
5530 		len = list_len(rettv->vval.v_list);
5531 		if (n1 < 0)
5532 		    n1 = len + n1;
5533 		if (!empty1 && (n1 < 0 || n1 >= len))
5534 		{
5535 		    /* For a range we allow invalid values and return an empty
5536 		     * list.  A list index out of range is an error. */
5537 		    if (!range)
5538 		    {
5539 			if (verbose)
5540 			    EMSGN(_(e_listidx), n1);
5541 			return FAIL;
5542 		    }
5543 		    n1 = len;
5544 		}
5545 		if (range)
5546 		{
5547 		    list_T	*l;
5548 		    listitem_T	*item;
5549 
5550 		    if (n2 < 0)
5551 			n2 = len + n2;
5552 		    else if (n2 >= len)
5553 			n2 = len - 1;
5554 		    if (!empty2 && (n2 < 0 || n2 + 1 < n1))
5555 			n2 = -1;
5556 		    l = list_alloc();
5557 		    if (l == NULL)
5558 			return FAIL;
5559 		    for (item = list_find(rettv->vval.v_list, n1);
5560 							       n1 <= n2; ++n1)
5561 		    {
5562 			if (list_append_tv(l, &item->li_tv) == FAIL)
5563 			{
5564 			    list_free(l, TRUE);
5565 			    return FAIL;
5566 			}
5567 			item = item->li_next;
5568 		    }
5569 		    clear_tv(rettv);
5570 		    rettv->v_type = VAR_LIST;
5571 		    rettv->vval.v_list = l;
5572 		    ++l->lv_refcount;
5573 		}
5574 		else
5575 		{
5576 		    copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1);
5577 		    clear_tv(rettv);
5578 		    *rettv = var1;
5579 		}
5580 		break;
5581 
5582 	    case VAR_DICT:
5583 		if (range)
5584 		{
5585 		    if (verbose)
5586 			EMSG(_(e_dictrange));
5587 		    if (len == -1)
5588 			clear_tv(&var1);
5589 		    return FAIL;
5590 		}
5591 		{
5592 		    dictitem_T	*item;
5593 
5594 		    if (len == -1)
5595 		    {
5596 			key = get_tv_string(&var1);
5597 			if (*key == NUL)
5598 			{
5599 			    if (verbose)
5600 				EMSG(_(e_emptykey));
5601 			    clear_tv(&var1);
5602 			    return FAIL;
5603 			}
5604 		    }
5605 
5606 		    item = dict_find(rettv->vval.v_dict, key, (int)len);
5607 
5608 		    if (item == NULL && verbose)
5609 			EMSG2(_(e_dictkey), key);
5610 		    if (len == -1)
5611 			clear_tv(&var1);
5612 		    if (item == NULL)
5613 			return FAIL;
5614 
5615 		    copy_tv(&item->di_tv, &var1);
5616 		    clear_tv(rettv);
5617 		    *rettv = var1;
5618 		}
5619 		break;
5620 	}
5621     }
5622 
5623     return OK;
5624 }
5625 
5626 /*
5627  * Get an option value.
5628  * "arg" points to the '&' or '+' before the option name.
5629  * "arg" is advanced to character after the option name.
5630  * Return OK or FAIL.
5631  */
5632     static int
5633 get_option_tv(
5634     char_u	**arg,
5635     typval_T	*rettv,	/* when NULL, only check if option exists */
5636     int		evaluate)
5637 {
5638     char_u	*option_end;
5639     long	numval;
5640     char_u	*stringval;
5641     int		opt_type;
5642     int		c;
5643     int		working = (**arg == '+');    /* has("+option") */
5644     int		ret = OK;
5645     int		opt_flags;
5646 
5647     /*
5648      * Isolate the option name and find its value.
5649      */
5650     option_end = find_option_end(arg, &opt_flags);
5651     if (option_end == NULL)
5652     {
5653 	if (rettv != NULL)
5654 	    EMSG2(_("E112: Option name missing: %s"), *arg);
5655 	return FAIL;
5656     }
5657 
5658     if (!evaluate)
5659     {
5660 	*arg = option_end;
5661 	return OK;
5662     }
5663 
5664     c = *option_end;
5665     *option_end = NUL;
5666     opt_type = get_option_value(*arg, &numval,
5667 			       rettv == NULL ? NULL : &stringval, opt_flags);
5668 
5669     if (opt_type == -3)			/* invalid name */
5670     {
5671 	if (rettv != NULL)
5672 	    EMSG2(_("E113: Unknown option: %s"), *arg);
5673 	ret = FAIL;
5674     }
5675     else if (rettv != NULL)
5676     {
5677 	if (opt_type == -2)		/* hidden string option */
5678 	{
5679 	    rettv->v_type = VAR_STRING;
5680 	    rettv->vval.v_string = NULL;
5681 	}
5682 	else if (opt_type == -1)	/* hidden number option */
5683 	{
5684 	    rettv->v_type = VAR_NUMBER;
5685 	    rettv->vval.v_number = 0;
5686 	}
5687 	else if (opt_type == 1)		/* number option */
5688 	{
5689 	    rettv->v_type = VAR_NUMBER;
5690 	    rettv->vval.v_number = numval;
5691 	}
5692 	else				/* string option */
5693 	{
5694 	    rettv->v_type = VAR_STRING;
5695 	    rettv->vval.v_string = stringval;
5696 	}
5697     }
5698     else if (working && (opt_type == -2 || opt_type == -1))
5699 	ret = FAIL;
5700 
5701     *option_end = c;		    /* put back for error messages */
5702     *arg = option_end;
5703 
5704     return ret;
5705 }
5706 
5707 /*
5708  * Allocate a variable for a string constant.
5709  * Return OK or FAIL.
5710  */
5711     static int
5712 get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
5713 {
5714     char_u	*p;
5715     char_u	*name;
5716     int		extra = 0;
5717 
5718     /*
5719      * Find the end of the string, skipping backslashed characters.
5720      */
5721     for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p))
5722     {
5723 	if (*p == '\\' && p[1] != NUL)
5724 	{
5725 	    ++p;
5726 	    /* A "\<x>" form occupies at least 4 characters, and produces up
5727 	     * to 6 characters: reserve space for 2 extra */
5728 	    if (*p == '<')
5729 		extra += 2;
5730 	}
5731     }
5732 
5733     if (*p != '"')
5734     {
5735 	EMSG2(_("E114: Missing quote: %s"), *arg);
5736 	return FAIL;
5737     }
5738 
5739     /* If only parsing, set *arg and return here */
5740     if (!evaluate)
5741     {
5742 	*arg = p + 1;
5743 	return OK;
5744     }
5745 
5746     /*
5747      * Copy the string into allocated memory, handling backslashed
5748      * characters.
5749      */
5750     name = alloc((unsigned)(p - *arg + extra));
5751     if (name == NULL)
5752 	return FAIL;
5753     rettv->v_type = VAR_STRING;
5754     rettv->vval.v_string = name;
5755 
5756     for (p = *arg + 1; *p != NUL && *p != '"'; )
5757     {
5758 	if (*p == '\\')
5759 	{
5760 	    switch (*++p)
5761 	    {
5762 		case 'b': *name++ = BS; ++p; break;
5763 		case 'e': *name++ = ESC; ++p; break;
5764 		case 'f': *name++ = FF; ++p; break;
5765 		case 'n': *name++ = NL; ++p; break;
5766 		case 'r': *name++ = CAR; ++p; break;
5767 		case 't': *name++ = TAB; ++p; break;
5768 
5769 		case 'X': /* hex: "\x1", "\x12" */
5770 		case 'x':
5771 		case 'u': /* Unicode: "\u0023" */
5772 		case 'U':
5773 			  if (vim_isxdigit(p[1]))
5774 			  {
5775 			      int	n, nr;
5776 			      int	c = toupper(*p);
5777 
5778 			      if (c == 'X')
5779 				  n = 2;
5780 			      else if (*p == 'u')
5781 				  n = 4;
5782 			      else
5783 				  n = 8;
5784 			      nr = 0;
5785 			      while (--n >= 0 && vim_isxdigit(p[1]))
5786 			      {
5787 				  ++p;
5788 				  nr = (nr << 4) + hex2nr(*p);
5789 			      }
5790 			      ++p;
5791 #ifdef FEAT_MBYTE
5792 			      /* For "\u" store the number according to
5793 			       * 'encoding'. */
5794 			      if (c != 'X')
5795 				  name += (*mb_char2bytes)(nr, name);
5796 			      else
5797 #endif
5798 				  *name++ = nr;
5799 			  }
5800 			  break;
5801 
5802 			  /* octal: "\1", "\12", "\123" */
5803 		case '0':
5804 		case '1':
5805 		case '2':
5806 		case '3':
5807 		case '4':
5808 		case '5':
5809 		case '6':
5810 		case '7': *name = *p++ - '0';
5811 			  if (*p >= '0' && *p <= '7')
5812 			  {
5813 			      *name = (*name << 3) + *p++ - '0';
5814 			      if (*p >= '0' && *p <= '7')
5815 				  *name = (*name << 3) + *p++ - '0';
5816 			  }
5817 			  ++name;
5818 			  break;
5819 
5820 			    /* Special key, e.g.: "\<C-W>" */
5821 		case '<': extra = trans_special(&p, name, TRUE);
5822 			  if (extra != 0)
5823 			  {
5824 			      name += extra;
5825 			      break;
5826 			  }
5827 			  /* FALLTHROUGH */
5828 
5829 		default:  MB_COPY_CHAR(p, name);
5830 			  break;
5831 	    }
5832 	}
5833 	else
5834 	    MB_COPY_CHAR(p, name);
5835 
5836     }
5837     *name = NUL;
5838     *arg = p + 1;
5839 
5840     return OK;
5841 }
5842 
5843 /*
5844  * Allocate a variable for a 'str''ing' constant.
5845  * Return OK or FAIL.
5846  */
5847     static int
5848 get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
5849 {
5850     char_u	*p;
5851     char_u	*str;
5852     int		reduce = 0;
5853 
5854     /*
5855      * Find the end of the string, skipping ''.
5856      */
5857     for (p = *arg + 1; *p != NUL; mb_ptr_adv(p))
5858     {
5859 	if (*p == '\'')
5860 	{
5861 	    if (p[1] != '\'')
5862 		break;
5863 	    ++reduce;
5864 	    ++p;
5865 	}
5866     }
5867 
5868     if (*p != '\'')
5869     {
5870 	EMSG2(_("E115: Missing quote: %s"), *arg);
5871 	return FAIL;
5872     }
5873 
5874     /* If only parsing return after setting "*arg" */
5875     if (!evaluate)
5876     {
5877 	*arg = p + 1;
5878 	return OK;
5879     }
5880 
5881     /*
5882      * Copy the string into allocated memory, handling '' to ' reduction.
5883      */
5884     str = alloc((unsigned)((p - *arg) - reduce));
5885     if (str == NULL)
5886 	return FAIL;
5887     rettv->v_type = VAR_STRING;
5888     rettv->vval.v_string = str;
5889 
5890     for (p = *arg + 1; *p != NUL; )
5891     {
5892 	if (*p == '\'')
5893 	{
5894 	    if (p[1] != '\'')
5895 		break;
5896 	    ++p;
5897 	}
5898 	MB_COPY_CHAR(p, str);
5899     }
5900     *str = NUL;
5901     *arg = p + 1;
5902 
5903     return OK;
5904 }
5905 
5906 /*
5907  * Allocate a variable for a List and fill it from "*arg".
5908  * Return OK or FAIL.
5909  */
5910     static int
5911 get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
5912 {
5913     list_T	*l = NULL;
5914     typval_T	tv;
5915     listitem_T	*item;
5916 
5917     if (evaluate)
5918     {
5919 	l = list_alloc();
5920 	if (l == NULL)
5921 	    return FAIL;
5922     }
5923 
5924     *arg = skipwhite(*arg + 1);
5925     while (**arg != ']' && **arg != NUL)
5926     {
5927 	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
5928 	    goto failret;
5929 	if (evaluate)
5930 	{
5931 	    item = listitem_alloc();
5932 	    if (item != NULL)
5933 	    {
5934 		item->li_tv = tv;
5935 		item->li_tv.v_lock = 0;
5936 		list_append(l, item);
5937 	    }
5938 	    else
5939 		clear_tv(&tv);
5940 	}
5941 
5942 	if (**arg == ']')
5943 	    break;
5944 	if (**arg != ',')
5945 	{
5946 	    EMSG2(_("E696: Missing comma in List: %s"), *arg);
5947 	    goto failret;
5948 	}
5949 	*arg = skipwhite(*arg + 1);
5950     }
5951 
5952     if (**arg != ']')
5953     {
5954 	EMSG2(_("E697: Missing end of List ']': %s"), *arg);
5955 failret:
5956 	if (evaluate)
5957 	    list_free(l, TRUE);
5958 	return FAIL;
5959     }
5960 
5961     *arg = skipwhite(*arg + 1);
5962     if (evaluate)
5963     {
5964 	rettv->v_type = VAR_LIST;
5965 	rettv->vval.v_list = l;
5966 	++l->lv_refcount;
5967     }
5968 
5969     return OK;
5970 }
5971 
5972 /*
5973  * Allocate an empty header for a list.
5974  * Caller should take care of the reference count.
5975  */
5976     list_T *
5977 list_alloc(void)
5978 {
5979     list_T  *l;
5980 
5981     l = (list_T *)alloc_clear(sizeof(list_T));
5982     if (l != NULL)
5983     {
5984 	/* Prepend the list to the list of lists for garbage collection. */
5985 	if (first_list != NULL)
5986 	    first_list->lv_used_prev = l;
5987 	l->lv_used_prev = NULL;
5988 	l->lv_used_next = first_list;
5989 	first_list = l;
5990     }
5991     return l;
5992 }
5993 
5994 /*
5995  * Allocate an empty list for a return value.
5996  * Returns OK or FAIL.
5997  */
5998     int
5999 rettv_list_alloc(typval_T *rettv)
6000 {
6001     list_T	*l = list_alloc();
6002 
6003     if (l == NULL)
6004 	return FAIL;
6005 
6006     rettv->vval.v_list = l;
6007     rettv->v_type = VAR_LIST;
6008     ++l->lv_refcount;
6009     return OK;
6010 }
6011 
6012 /*
6013  * Unreference a list: decrement the reference count and free it when it
6014  * becomes zero.
6015  */
6016     void
6017 list_unref(list_T *l)
6018 {
6019     if (l != NULL && --l->lv_refcount <= 0)
6020 	list_free(l, TRUE);
6021 }
6022 
6023 /*
6024  * Free a list, including all non-container items it points to.
6025  * Ignores the reference count.
6026  */
6027     void
6028 list_free(
6029     list_T  *l,
6030     int	    recurse)	/* Free Lists and Dictionaries recursively. */
6031 {
6032     listitem_T *item;
6033 
6034     /* Remove the list from the list of lists for garbage collection. */
6035     if (l->lv_used_prev == NULL)
6036 	first_list = l->lv_used_next;
6037     else
6038 	l->lv_used_prev->lv_used_next = l->lv_used_next;
6039     if (l->lv_used_next != NULL)
6040 	l->lv_used_next->lv_used_prev = l->lv_used_prev;
6041 
6042     for (item = l->lv_first; item != NULL; item = l->lv_first)
6043     {
6044 	/* Remove the item before deleting it. */
6045 	l->lv_first = item->li_next;
6046 	if (recurse || (item->li_tv.v_type != VAR_LIST
6047 					   && item->li_tv.v_type != VAR_DICT))
6048 	    clear_tv(&item->li_tv);
6049 	vim_free(item);
6050     }
6051     vim_free(l);
6052 }
6053 
6054 /*
6055  * Allocate a list item.
6056  * It is not initialized, don't forget to set v_lock.
6057  */
6058     listitem_T *
6059 listitem_alloc(void)
6060 {
6061     return (listitem_T *)alloc(sizeof(listitem_T));
6062 }
6063 
6064 /*
6065  * Free a list item.  Also clears the value.  Does not notify watchers.
6066  */
6067     void
6068 listitem_free(listitem_T *item)
6069 {
6070     clear_tv(&item->li_tv);
6071     vim_free(item);
6072 }
6073 
6074 /*
6075  * Remove a list item from a List and free it.  Also clears the value.
6076  */
6077     void
6078 listitem_remove(list_T *l, listitem_T *item)
6079 {
6080     vimlist_remove(l, item, item);
6081     listitem_free(item);
6082 }
6083 
6084 /*
6085  * Get the number of items in a list.
6086  */
6087     static long
6088 list_len(list_T *l)
6089 {
6090     if (l == NULL)
6091 	return 0L;
6092     return l->lv_len;
6093 }
6094 
6095 /*
6096  * Return TRUE when two lists have exactly the same values.
6097  */
6098     static int
6099 list_equal(
6100     list_T	*l1,
6101     list_T	*l2,
6102     int		ic,	/* ignore case for strings */
6103     int		recursive)  /* TRUE when used recursively */
6104 {
6105     listitem_T	*item1, *item2;
6106 
6107     if (l1 == NULL || l2 == NULL)
6108 	return FALSE;
6109     if (l1 == l2)
6110 	return TRUE;
6111     if (list_len(l1) != list_len(l2))
6112 	return FALSE;
6113 
6114     for (item1 = l1->lv_first, item2 = l2->lv_first;
6115 	    item1 != NULL && item2 != NULL;
6116 			       item1 = item1->li_next, item2 = item2->li_next)
6117 	if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive))
6118 	    return FALSE;
6119     return item1 == NULL && item2 == NULL;
6120 }
6121 
6122 /*
6123  * Return the dictitem that an entry in a hashtable points to.
6124  */
6125     dictitem_T *
6126 dict_lookup(hashitem_T *hi)
6127 {
6128     return HI2DI(hi);
6129 }
6130 
6131 /*
6132  * Return TRUE when two dictionaries have exactly the same key/values.
6133  */
6134     static int
6135 dict_equal(
6136     dict_T	*d1,
6137     dict_T	*d2,
6138     int		ic,	/* ignore case for strings */
6139     int		recursive) /* TRUE when used recursively */
6140 {
6141     hashitem_T	*hi;
6142     dictitem_T	*item2;
6143     int		todo;
6144 
6145     if (d1 == NULL || d2 == NULL)
6146 	return FALSE;
6147     if (d1 == d2)
6148 	return TRUE;
6149     if (dict_len(d1) != dict_len(d2))
6150 	return FALSE;
6151 
6152     todo = (int)d1->dv_hashtab.ht_used;
6153     for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi)
6154     {
6155 	if (!HASHITEM_EMPTY(hi))
6156 	{
6157 	    item2 = dict_find(d2, hi->hi_key, -1);
6158 	    if (item2 == NULL)
6159 		return FALSE;
6160 	    if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive))
6161 		return FALSE;
6162 	    --todo;
6163 	}
6164     }
6165     return TRUE;
6166 }
6167 
6168 static int tv_equal_recurse_limit;
6169 
6170 /*
6171  * Return TRUE if "tv1" and "tv2" have the same value.
6172  * Compares the items just like "==" would compare them, but strings and
6173  * numbers are different.  Floats and numbers are also different.
6174  */
6175     static int
6176 tv_equal(
6177     typval_T *tv1,
6178     typval_T *tv2,
6179     int	     ic,	    /* ignore case */
6180     int	     recursive)	    /* TRUE when used recursively */
6181 {
6182     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
6183     char_u	*s1, *s2;
6184     static int  recursive_cnt = 0;	    /* catch recursive loops */
6185     int		r;
6186 
6187     /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */
6188     if ((tv1->v_type == VAR_FUNC
6189 		|| (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
6190 	    && (tv2->v_type == VAR_FUNC
6191 		|| (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
6192     {
6193 	s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
6194 					       : tv1->vval.v_partial->pt_name;
6195 	s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
6196 					       : tv2->vval.v_partial->pt_name;
6197 	return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0);
6198     }
6199 
6200     if (tv1->v_type != tv2->v_type)
6201 	return FALSE;
6202 
6203     /* Catch lists and dicts that have an endless loop by limiting
6204      * recursiveness to a limit.  We guess they are equal then.
6205      * A fixed limit has the problem of still taking an awful long time.
6206      * Reduce the limit every time running into it. That should work fine for
6207      * deeply linked structures that are not recursively linked and catch
6208      * recursiveness quickly. */
6209     if (!recursive)
6210 	tv_equal_recurse_limit = 1000;
6211     if (recursive_cnt >= tv_equal_recurse_limit)
6212     {
6213 	--tv_equal_recurse_limit;
6214 	return TRUE;
6215     }
6216 
6217     switch (tv1->v_type)
6218     {
6219 	case VAR_LIST:
6220 	    ++recursive_cnt;
6221 	    r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
6222 	    --recursive_cnt;
6223 	    return r;
6224 
6225 	case VAR_DICT:
6226 	    ++recursive_cnt;
6227 	    r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
6228 	    --recursive_cnt;
6229 	    return r;
6230 
6231 	case VAR_NUMBER:
6232 	    return tv1->vval.v_number == tv2->vval.v_number;
6233 
6234 	case VAR_STRING:
6235 	    s1 = get_tv_string_buf(tv1, buf1);
6236 	    s2 = get_tv_string_buf(tv2, buf2);
6237 	    return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
6238 
6239 	case VAR_SPECIAL:
6240 	    return tv1->vval.v_number == tv2->vval.v_number;
6241 
6242 	case VAR_FLOAT:
6243 #ifdef FEAT_FLOAT
6244 	    return tv1->vval.v_float == tv2->vval.v_float;
6245 #endif
6246 	case VAR_JOB:
6247 #ifdef FEAT_JOB_CHANNEL
6248 	    return tv1->vval.v_job == tv2->vval.v_job;
6249 #endif
6250 	case VAR_CHANNEL:
6251 #ifdef FEAT_JOB_CHANNEL
6252 	    return tv1->vval.v_channel == tv2->vval.v_channel;
6253 #endif
6254 	case VAR_FUNC:
6255 	case VAR_PARTIAL:
6256 	case VAR_UNKNOWN:
6257 	    break;
6258     }
6259 
6260     /* VAR_UNKNOWN can be the result of a invalid expression, let's say it
6261      * does not equal anything, not even itself. */
6262     return FALSE;
6263 }
6264 
6265 /*
6266  * Locate item with index "n" in list "l" and return it.
6267  * A negative index is counted from the end; -1 is the last item.
6268  * Returns NULL when "n" is out of range.
6269  */
6270     listitem_T *
6271 list_find(list_T *l, long n)
6272 {
6273     listitem_T	*item;
6274     long	idx;
6275 
6276     if (l == NULL)
6277 	return NULL;
6278 
6279     /* Negative index is relative to the end. */
6280     if (n < 0)
6281 	n = l->lv_len + n;
6282 
6283     /* Check for index out of range. */
6284     if (n < 0 || n >= l->lv_len)
6285 	return NULL;
6286 
6287     /* When there is a cached index may start search from there. */
6288     if (l->lv_idx_item != NULL)
6289     {
6290 	if (n < l->lv_idx / 2)
6291 	{
6292 	    /* closest to the start of the list */
6293 	    item = l->lv_first;
6294 	    idx = 0;
6295 	}
6296 	else if (n > (l->lv_idx + l->lv_len) / 2)
6297 	{
6298 	    /* closest to the end of the list */
6299 	    item = l->lv_last;
6300 	    idx = l->lv_len - 1;
6301 	}
6302 	else
6303 	{
6304 	    /* closest to the cached index */
6305 	    item = l->lv_idx_item;
6306 	    idx = l->lv_idx;
6307 	}
6308     }
6309     else
6310     {
6311 	if (n < l->lv_len / 2)
6312 	{
6313 	    /* closest to the start of the list */
6314 	    item = l->lv_first;
6315 	    idx = 0;
6316 	}
6317 	else
6318 	{
6319 	    /* closest to the end of the list */
6320 	    item = l->lv_last;
6321 	    idx = l->lv_len - 1;
6322 	}
6323     }
6324 
6325     while (n > idx)
6326     {
6327 	/* search forward */
6328 	item = item->li_next;
6329 	++idx;
6330     }
6331     while (n < idx)
6332     {
6333 	/* search backward */
6334 	item = item->li_prev;
6335 	--idx;
6336     }
6337 
6338     /* cache the used index */
6339     l->lv_idx = idx;
6340     l->lv_idx_item = item;
6341 
6342     return item;
6343 }
6344 
6345 /*
6346  * Get list item "l[idx]" as a number.
6347  */
6348     static long
6349 list_find_nr(
6350     list_T	*l,
6351     long	idx,
6352     int		*errorp)	/* set to TRUE when something wrong */
6353 {
6354     listitem_T	*li;
6355 
6356     li = list_find(l, idx);
6357     if (li == NULL)
6358     {
6359 	if (errorp != NULL)
6360 	    *errorp = TRUE;
6361 	return -1L;
6362     }
6363     return get_tv_number_chk(&li->li_tv, errorp);
6364 }
6365 
6366 /*
6367  * Get list item "l[idx - 1]" as a string.  Returns NULL for failure.
6368  */
6369     char_u *
6370 list_find_str(list_T *l, long idx)
6371 {
6372     listitem_T	*li;
6373 
6374     li = list_find(l, idx - 1);
6375     if (li == NULL)
6376     {
6377 	EMSGN(_(e_listidx), idx);
6378 	return NULL;
6379     }
6380     return get_tv_string(&li->li_tv);
6381 }
6382 
6383 /*
6384  * Locate "item" list "l" and return its index.
6385  * Returns -1 when "item" is not in the list.
6386  */
6387     static long
6388 list_idx_of_item(list_T *l, listitem_T *item)
6389 {
6390     long	idx = 0;
6391     listitem_T	*li;
6392 
6393     if (l == NULL)
6394 	return -1;
6395     idx = 0;
6396     for (li = l->lv_first; li != NULL && li != item; li = li->li_next)
6397 	++idx;
6398     if (li == NULL)
6399 	return -1;
6400     return idx;
6401 }
6402 
6403 /*
6404  * Append item "item" to the end of list "l".
6405  */
6406     void
6407 list_append(list_T *l, listitem_T *item)
6408 {
6409     if (l->lv_last == NULL)
6410     {
6411 	/* empty list */
6412 	l->lv_first = item;
6413 	l->lv_last = item;
6414 	item->li_prev = NULL;
6415     }
6416     else
6417     {
6418 	l->lv_last->li_next = item;
6419 	item->li_prev = l->lv_last;
6420 	l->lv_last = item;
6421     }
6422     ++l->lv_len;
6423     item->li_next = NULL;
6424 }
6425 
6426 /*
6427  * Append typval_T "tv" to the end of list "l".
6428  * Return FAIL when out of memory.
6429  */
6430     int
6431 list_append_tv(list_T *l, typval_T *tv)
6432 {
6433     listitem_T	*li = listitem_alloc();
6434 
6435     if (li == NULL)
6436 	return FAIL;
6437     copy_tv(tv, &li->li_tv);
6438     list_append(l, li);
6439     return OK;
6440 }
6441 
6442 /*
6443  * Add a dictionary to a list.  Used by getqflist().
6444  * Return FAIL when out of memory.
6445  */
6446     int
6447 list_append_dict(list_T *list, dict_T *dict)
6448 {
6449     listitem_T	*li = listitem_alloc();
6450 
6451     if (li == NULL)
6452 	return FAIL;
6453     li->li_tv.v_type = VAR_DICT;
6454     li->li_tv.v_lock = 0;
6455     li->li_tv.vval.v_dict = dict;
6456     list_append(list, li);
6457     ++dict->dv_refcount;
6458     return OK;
6459 }
6460 
6461 /*
6462  * Make a copy of "str" and append it as an item to list "l".
6463  * When "len" >= 0 use "str[len]".
6464  * Returns FAIL when out of memory.
6465  */
6466     int
6467 list_append_string(list_T *l, char_u *str, int len)
6468 {
6469     listitem_T *li = listitem_alloc();
6470 
6471     if (li == NULL)
6472 	return FAIL;
6473     list_append(l, li);
6474     li->li_tv.v_type = VAR_STRING;
6475     li->li_tv.v_lock = 0;
6476     if (str == NULL)
6477 	li->li_tv.vval.v_string = NULL;
6478     else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len)
6479 						 : vim_strsave(str))) == NULL)
6480 	return FAIL;
6481     return OK;
6482 }
6483 
6484 /*
6485  * Append "n" to list "l".
6486  * Returns FAIL when out of memory.
6487  */
6488     int
6489 list_append_number(list_T *l, varnumber_T n)
6490 {
6491     listitem_T	*li;
6492 
6493     li = listitem_alloc();
6494     if (li == NULL)
6495 	return FAIL;
6496     li->li_tv.v_type = VAR_NUMBER;
6497     li->li_tv.v_lock = 0;
6498     li->li_tv.vval.v_number = n;
6499     list_append(l, li);
6500     return OK;
6501 }
6502 
6503 /*
6504  * Insert typval_T "tv" in list "l" before "item".
6505  * If "item" is NULL append at the end.
6506  * Return FAIL when out of memory.
6507  */
6508     int
6509 list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
6510 {
6511     listitem_T	*ni = listitem_alloc();
6512 
6513     if (ni == NULL)
6514 	return FAIL;
6515     copy_tv(tv, &ni->li_tv);
6516     list_insert(l, ni, item);
6517     return OK;
6518 }
6519 
6520     void
6521 list_insert(list_T *l, listitem_T *ni, listitem_T *item)
6522 {
6523     if (item == NULL)
6524 	/* Append new item at end of list. */
6525 	list_append(l, ni);
6526     else
6527     {
6528 	/* Insert new item before existing item. */
6529 	ni->li_prev = item->li_prev;
6530 	ni->li_next = item;
6531 	if (item->li_prev == NULL)
6532 	{
6533 	    l->lv_first = ni;
6534 	    ++l->lv_idx;
6535 	}
6536 	else
6537 	{
6538 	    item->li_prev->li_next = ni;
6539 	    l->lv_idx_item = NULL;
6540 	}
6541 	item->li_prev = ni;
6542 	++l->lv_len;
6543     }
6544 }
6545 
6546 /*
6547  * Extend "l1" with "l2".
6548  * If "bef" is NULL append at the end, otherwise insert before this item.
6549  * Returns FAIL when out of memory.
6550  */
6551     static int
6552 list_extend(list_T *l1, list_T *l2, listitem_T *bef)
6553 {
6554     listitem_T	*item;
6555     int		todo = l2->lv_len;
6556 
6557     /* We also quit the loop when we have inserted the original item count of
6558      * the list, avoid a hang when we extend a list with itself. */
6559     for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next)
6560 	if (list_insert_tv(l1, &item->li_tv, bef) == FAIL)
6561 	    return FAIL;
6562     return OK;
6563 }
6564 
6565 /*
6566  * Concatenate lists "l1" and "l2" into a new list, stored in "tv".
6567  * Return FAIL when out of memory.
6568  */
6569     static int
6570 list_concat(list_T *l1, list_T *l2, typval_T *tv)
6571 {
6572     list_T	*l;
6573 
6574     if (l1 == NULL || l2 == NULL)
6575 	return FAIL;
6576 
6577     /* make a copy of the first list. */
6578     l = list_copy(l1, FALSE, 0);
6579     if (l == NULL)
6580 	return FAIL;
6581     tv->v_type = VAR_LIST;
6582     tv->vval.v_list = l;
6583 
6584     /* append all items from the second list */
6585     return list_extend(l, l2, NULL);
6586 }
6587 
6588 /*
6589  * Make a copy of list "orig".  Shallow if "deep" is FALSE.
6590  * The refcount of the new list is set to 1.
6591  * See item_copy() for "copyID".
6592  * Returns NULL when out of memory.
6593  */
6594     static list_T *
6595 list_copy(list_T *orig, int deep, int copyID)
6596 {
6597     list_T	*copy;
6598     listitem_T	*item;
6599     listitem_T	*ni;
6600 
6601     if (orig == NULL)
6602 	return NULL;
6603 
6604     copy = list_alloc();
6605     if (copy != NULL)
6606     {
6607 	if (copyID != 0)
6608 	{
6609 	    /* Do this before adding the items, because one of the items may
6610 	     * refer back to this list. */
6611 	    orig->lv_copyID = copyID;
6612 	    orig->lv_copylist = copy;
6613 	}
6614 	for (item = orig->lv_first; item != NULL && !got_int;
6615 							 item = item->li_next)
6616 	{
6617 	    ni = listitem_alloc();
6618 	    if (ni == NULL)
6619 		break;
6620 	    if (deep)
6621 	    {
6622 		if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL)
6623 		{
6624 		    vim_free(ni);
6625 		    break;
6626 		}
6627 	    }
6628 	    else
6629 		copy_tv(&item->li_tv, &ni->li_tv);
6630 	    list_append(copy, ni);
6631 	}
6632 	++copy->lv_refcount;
6633 	if (item != NULL)
6634 	{
6635 	    list_unref(copy);
6636 	    copy = NULL;
6637 	}
6638     }
6639 
6640     return copy;
6641 }
6642 
6643 /*
6644  * Remove items "item" to "item2" from list "l".
6645  * Does not free the listitem or the value!
6646  * This used to be called list_remove, but that conflicts with a Sun header
6647  * file.
6648  */
6649     void
6650 vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2)
6651 {
6652     listitem_T	*ip;
6653 
6654     /* notify watchers */
6655     for (ip = item; ip != NULL; ip = ip->li_next)
6656     {
6657 	--l->lv_len;
6658 	list_fix_watch(l, ip);
6659 	if (ip == item2)
6660 	    break;
6661     }
6662 
6663     if (item2->li_next == NULL)
6664 	l->lv_last = item->li_prev;
6665     else
6666 	item2->li_next->li_prev = item->li_prev;
6667     if (item->li_prev == NULL)
6668 	l->lv_first = item2->li_next;
6669     else
6670 	item->li_prev->li_next = item2->li_next;
6671     l->lv_idx_item = NULL;
6672 }
6673 
6674 /*
6675  * Return an allocated string with the string representation of a list.
6676  * May return NULL.
6677  */
6678     static char_u *
6679 list2string(typval_T *tv, int copyID)
6680 {
6681     garray_T	ga;
6682 
6683     if (tv->vval.v_list == NULL)
6684 	return NULL;
6685     ga_init2(&ga, (int)sizeof(char), 80);
6686     ga_append(&ga, '[');
6687     if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL)
6688     {
6689 	vim_free(ga.ga_data);
6690 	return NULL;
6691     }
6692     ga_append(&ga, ']');
6693     ga_append(&ga, NUL);
6694     return (char_u *)ga.ga_data;
6695 }
6696 
6697 typedef struct join_S {
6698     char_u	*s;
6699     char_u	*tofree;
6700 } join_T;
6701 
6702     static int
6703 list_join_inner(
6704     garray_T	*gap,		/* to store the result in */
6705     list_T	*l,
6706     char_u	*sep,
6707     int		echo_style,
6708     int		copyID,
6709     garray_T	*join_gap)	/* to keep each list item string */
6710 {
6711     int		i;
6712     join_T	*p;
6713     int		len;
6714     int		sumlen = 0;
6715     int		first = TRUE;
6716     char_u	*tofree;
6717     char_u	numbuf[NUMBUFLEN];
6718     listitem_T	*item;
6719     char_u	*s;
6720 
6721     /* Stringify each item in the list. */
6722     for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
6723     {
6724 	if (echo_style)
6725 	    s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
6726 	else
6727 	    s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
6728 	if (s == NULL)
6729 	    return FAIL;
6730 
6731 	len = (int)STRLEN(s);
6732 	sumlen += len;
6733 
6734 	(void)ga_grow(join_gap, 1);
6735 	p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++);
6736 	if (tofree != NULL || s != numbuf)
6737 	{
6738 	    p->s = s;
6739 	    p->tofree = tofree;
6740 	}
6741 	else
6742 	{
6743 	    p->s = vim_strnsave(s, len);
6744 	    p->tofree = p->s;
6745 	}
6746 
6747 	line_breakcheck();
6748 	if (did_echo_string_emsg)  /* recursion error, bail out */
6749 	    break;
6750     }
6751 
6752     /* Allocate result buffer with its total size, avoid re-allocation and
6753      * multiple copy operations.  Add 2 for a tailing ']' and NUL. */
6754     if (join_gap->ga_len >= 2)
6755 	sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1);
6756     if (ga_grow(gap, sumlen + 2) == FAIL)
6757 	return FAIL;
6758 
6759     for (i = 0; i < join_gap->ga_len && !got_int; ++i)
6760     {
6761 	if (first)
6762 	    first = FALSE;
6763 	else
6764 	    ga_concat(gap, sep);
6765 	p = ((join_T *)join_gap->ga_data) + i;
6766 
6767 	if (p->s != NULL)
6768 	    ga_concat(gap, p->s);
6769 	line_breakcheck();
6770     }
6771 
6772     return OK;
6773 }
6774 
6775 /*
6776  * Join list "l" into a string in "*gap", using separator "sep".
6777  * When "echo_style" is TRUE use String as echoed, otherwise as inside a List.
6778  * Return FAIL or OK.
6779  */
6780     static int
6781 list_join(
6782     garray_T	*gap,
6783     list_T	*l,
6784     char_u	*sep,
6785     int		echo_style,
6786     int		copyID)
6787 {
6788     garray_T	join_ga;
6789     int		retval;
6790     join_T	*p;
6791     int		i;
6792 
6793     if (l->lv_len < 1)
6794 	return OK; /* nothing to do */
6795     ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
6796     retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga);
6797 
6798     /* Dispose each item in join_ga. */
6799     if (join_ga.ga_data != NULL)
6800     {
6801 	p = (join_T *)join_ga.ga_data;
6802 	for (i = 0; i < join_ga.ga_len; ++i)
6803 	{
6804 	    vim_free(p->tofree);
6805 	    ++p;
6806 	}
6807 	ga_clear(&join_ga);
6808     }
6809 
6810     return retval;
6811 }
6812 
6813 /*
6814  * Return the next (unique) copy ID.
6815  * Used for serializing nested structures.
6816  */
6817     int
6818 get_copyID(void)
6819 {
6820     current_copyID += COPYID_INC;
6821     return current_copyID;
6822 }
6823 
6824 /*
6825  * Garbage collection for lists and dictionaries.
6826  *
6827  * We use reference counts to be able to free most items right away when they
6828  * are no longer used.  But for composite items it's possible that it becomes
6829  * unused while the reference count is > 0: When there is a recursive
6830  * reference.  Example:
6831  *	:let l = [1, 2, 3]
6832  *	:let d = {9: l}
6833  *	:let l[1] = d
6834  *
6835  * Since this is quite unusual we handle this with garbage collection: every
6836  * once in a while find out which lists and dicts are not referenced from any
6837  * variable.
6838  *
6839  * Here is a good reference text about garbage collection (refers to Python
6840  * but it applies to all reference-counting mechanisms):
6841  *	http://python.ca/nas/python/gc/
6842  */
6843 
6844 /*
6845  * Do garbage collection for lists and dicts.
6846  * Return TRUE if some memory was freed.
6847  */
6848     int
6849 garbage_collect(void)
6850 {
6851     int		copyID;
6852     int		abort = FALSE;
6853     buf_T	*buf;
6854     win_T	*wp;
6855     int		i;
6856     funccall_T	*fc, **pfc;
6857     int		did_free = FALSE;
6858     int		did_free_funccal = FALSE;
6859 #ifdef FEAT_WINDOWS
6860     tabpage_T	*tp;
6861 #endif
6862 
6863     /* Only do this once. */
6864     want_garbage_collect = FALSE;
6865     may_garbage_collect = FALSE;
6866     garbage_collect_at_exit = FALSE;
6867 
6868     /* We advance by two because we add one for items referenced through
6869      * previous_funccal. */
6870     copyID = get_copyID();
6871 
6872     /*
6873      * 1. Go through all accessible variables and mark all lists and dicts
6874      *    with copyID.
6875      */
6876 
6877     /* Don't free variables in the previous_funccal list unless they are only
6878      * referenced through previous_funccal.  This must be first, because if
6879      * the item is referenced elsewhere the funccal must not be freed. */
6880     for (fc = previous_funccal; fc != NULL; fc = fc->caller)
6881     {
6882 	abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1,
6883 									NULL);
6884 	abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1,
6885 									NULL);
6886     }
6887 
6888     /* script-local variables */
6889     for (i = 1; i <= ga_scripts.ga_len; ++i)
6890 	abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL);
6891 
6892     /* buffer-local variables */
6893     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
6894 	abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID,
6895 								  NULL, NULL);
6896 
6897     /* window-local variables */
6898     FOR_ALL_TAB_WINDOWS(tp, wp)
6899 	abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
6900 								  NULL, NULL);
6901 #ifdef FEAT_AUTOCMD
6902     if (aucmd_win != NULL)
6903 	abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID,
6904 								  NULL, NULL);
6905 #endif
6906 
6907 #ifdef FEAT_WINDOWS
6908     /* tabpage-local variables */
6909     for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
6910 	abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID,
6911 								  NULL, NULL);
6912 #endif
6913 
6914     /* global variables */
6915     abort = abort || set_ref_in_ht(&globvarht, copyID, NULL);
6916 
6917     /* function-local variables */
6918     for (fc = current_funccal; fc != NULL; fc = fc->caller)
6919     {
6920 	abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL);
6921 	abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL);
6922     }
6923 
6924     /* v: vars */
6925     abort = abort || set_ref_in_ht(&vimvarht, copyID, NULL);
6926 
6927 #ifdef FEAT_LUA
6928     abort = abort || set_ref_in_lua(copyID);
6929 #endif
6930 
6931 #ifdef FEAT_PYTHON
6932     abort = abort || set_ref_in_python(copyID);
6933 #endif
6934 
6935 #ifdef FEAT_PYTHON3
6936     abort = abort || set_ref_in_python3(copyID);
6937 #endif
6938 
6939 #ifdef FEAT_JOB_CHANNEL
6940     abort = abort || set_ref_in_channel(copyID);
6941 #endif
6942 
6943     if (!abort)
6944     {
6945 	/*
6946 	 * 2. Free lists and dictionaries that are not referenced.
6947 	 */
6948 	did_free = free_unref_items(copyID);
6949 
6950 	/*
6951 	 * 3. Check if any funccal can be freed now.
6952 	 */
6953 	for (pfc = &previous_funccal; *pfc != NULL; )
6954 	{
6955 	    if (can_free_funccal(*pfc, copyID))
6956 	    {
6957 		fc = *pfc;
6958 		*pfc = fc->caller;
6959 		free_funccal(fc, TRUE);
6960 		did_free = TRUE;
6961 		did_free_funccal = TRUE;
6962 	    }
6963 	    else
6964 		pfc = &(*pfc)->caller;
6965 	}
6966 	if (did_free_funccal)
6967 	    /* When a funccal was freed some more items might be garbage
6968 	     * collected, so run again. */
6969 	    (void)garbage_collect();
6970     }
6971     else if (p_verbose > 0)
6972     {
6973 	verb_msg((char_u *)_("Not enough memory to set references, garbage collection aborted!"));
6974     }
6975 
6976     return did_free;
6977 }
6978 
6979 /*
6980  * Free lists, dictionaries and jobs that are no longer referenced.
6981  */
6982     static int
6983 free_unref_items(int copyID)
6984 {
6985     dict_T	*dd, *dd_next;
6986     list_T	*ll, *ll_next;
6987     int		did_free = FALSE;
6988 
6989     /*
6990      * Go through the list of dicts and free items without the copyID.
6991      */
6992     for (dd = first_dict; dd != NULL; )
6993     {
6994 	dd_next = dd->dv_used_next;
6995 	if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
6996 	{
6997 	    /* Free the Dictionary and ordinary items it contains, but don't
6998 	     * recurse into Lists and Dictionaries, they will be in the list
6999 	     * of dicts or list of lists. */
7000 	    dict_free(dd, FALSE);
7001 	    did_free = TRUE;
7002 	}
7003 	dd = dd_next;
7004     }
7005 
7006     /*
7007      * Go through the list of lists and free items without the copyID.
7008      * But don't free a list that has a watcher (used in a for loop), these
7009      * are not referenced anywhere.
7010      */
7011     for (ll = first_list; ll != NULL; )
7012     {
7013 	ll_next = ll->lv_used_next;
7014 	if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
7015 						      && ll->lv_watch == NULL)
7016 	{
7017 	    /* Free the List and ordinary items it contains, but don't recurse
7018 	     * into Lists and Dictionaries, they will be in the list of dicts
7019 	     * or list of lists. */
7020 	    list_free(ll, FALSE);
7021 	    did_free = TRUE;
7022 	}
7023 	ll = ll_next;
7024     }
7025 
7026     return did_free;
7027 }
7028 
7029 /*
7030  * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
7031  * "list_stack" is used to add lists to be marked.  Can be NULL.
7032  *
7033  * Returns TRUE if setting references failed somehow.
7034  */
7035     int
7036 set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
7037 {
7038     int		todo;
7039     int		abort = FALSE;
7040     hashitem_T	*hi;
7041     hashtab_T	*cur_ht;
7042     ht_stack_T	*ht_stack = NULL;
7043     ht_stack_T	*tempitem;
7044 
7045     cur_ht = ht;
7046     for (;;)
7047     {
7048 	if (!abort)
7049 	{
7050 	    /* Mark each item in the hashtab.  If the item contains a hashtab
7051 	     * it is added to ht_stack, if it contains a list it is added to
7052 	     * list_stack. */
7053 	    todo = (int)cur_ht->ht_used;
7054 	    for (hi = cur_ht->ht_array; todo > 0; ++hi)
7055 		if (!HASHITEM_EMPTY(hi))
7056 		{
7057 		    --todo;
7058 		    abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID,
7059 						       &ht_stack, list_stack);
7060 		}
7061 	}
7062 
7063 	if (ht_stack == NULL)
7064 	    break;
7065 
7066 	/* take an item from the stack */
7067 	cur_ht = ht_stack->ht;
7068 	tempitem = ht_stack;
7069 	ht_stack = ht_stack->prev;
7070 	free(tempitem);
7071     }
7072 
7073     return abort;
7074 }
7075 
7076 /*
7077  * Mark all lists and dicts referenced through list "l" with "copyID".
7078  * "ht_stack" is used to add hashtabs to be marked.  Can be NULL.
7079  *
7080  * Returns TRUE if setting references failed somehow.
7081  */
7082     int
7083 set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack)
7084 {
7085     listitem_T	 *li;
7086     int		 abort = FALSE;
7087     list_T	 *cur_l;
7088     list_stack_T *list_stack = NULL;
7089     list_stack_T *tempitem;
7090 
7091     cur_l = l;
7092     for (;;)
7093     {
7094 	if (!abort)
7095 	    /* Mark each item in the list.  If the item contains a hashtab
7096 	     * it is added to ht_stack, if it contains a list it is added to
7097 	     * list_stack. */
7098 	    for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next)
7099 		abort = abort || set_ref_in_item(&li->li_tv, copyID,
7100 						       ht_stack, &list_stack);
7101 	if (list_stack == NULL)
7102 	    break;
7103 
7104 	/* take an item from the stack */
7105 	cur_l = list_stack->list;
7106 	tempitem = list_stack;
7107 	list_stack = list_stack->prev;
7108 	free(tempitem);
7109     }
7110 
7111     return abort;
7112 }
7113 
7114 /*
7115  * Mark all lists and dicts referenced through typval "tv" with "copyID".
7116  * "list_stack" is used to add lists to be marked.  Can be NULL.
7117  * "ht_stack" is used to add hashtabs to be marked.  Can be NULL.
7118  *
7119  * Returns TRUE if setting references failed somehow.
7120  */
7121     int
7122 set_ref_in_item(
7123     typval_T	    *tv,
7124     int		    copyID,
7125     ht_stack_T	    **ht_stack,
7126     list_stack_T    **list_stack)
7127 {
7128     dict_T	*dd;
7129     list_T	*ll;
7130     int		abort = FALSE;
7131 
7132     if (tv->v_type == VAR_DICT)
7133     {
7134 	dd = tv->vval.v_dict;
7135 	if (dd != NULL && dd->dv_copyID != copyID)
7136 	{
7137 	    /* Didn't see this dict yet. */
7138 	    dd->dv_copyID = copyID;
7139 	    if (ht_stack == NULL)
7140 	    {
7141 		abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
7142 	    }
7143 	    else
7144 	    {
7145 		ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T));
7146 		if (newitem == NULL)
7147 		    abort = TRUE;
7148 		else
7149 		{
7150 		    newitem->ht = &dd->dv_hashtab;
7151 		    newitem->prev = *ht_stack;
7152 		    *ht_stack = newitem;
7153 		}
7154 	    }
7155 	}
7156     }
7157     else if (tv->v_type == VAR_LIST)
7158     {
7159 	ll = tv->vval.v_list;
7160 	if (ll != NULL && ll->lv_copyID != copyID)
7161 	{
7162 	    /* Didn't see this list yet. */
7163 	    ll->lv_copyID = copyID;
7164 	    if (list_stack == NULL)
7165 	    {
7166 		abort = set_ref_in_list(ll, copyID, ht_stack);
7167 	    }
7168 	    else
7169 	    {
7170 		list_stack_T *newitem = (list_stack_T*)malloc(
7171 							sizeof(list_stack_T));
7172 		if (newitem == NULL)
7173 		    abort = TRUE;
7174 		else
7175 		{
7176 		    newitem->list = ll;
7177 		    newitem->prev = *list_stack;
7178 		    *list_stack = newitem;
7179 		}
7180 	    }
7181 	}
7182     }
7183     return abort;
7184 }
7185 
7186 /*
7187  * Allocate an empty header for a dictionary.
7188  */
7189     dict_T *
7190 dict_alloc(void)
7191 {
7192     dict_T *d;
7193 
7194     d = (dict_T *)alloc(sizeof(dict_T));
7195     if (d != NULL)
7196     {
7197 	/* Add the dict to the list of dicts for garbage collection. */
7198 	if (first_dict != NULL)
7199 	    first_dict->dv_used_prev = d;
7200 	d->dv_used_next = first_dict;
7201 	d->dv_used_prev = NULL;
7202 	first_dict = d;
7203 
7204 	hash_init(&d->dv_hashtab);
7205 	d->dv_lock = 0;
7206 	d->dv_scope = 0;
7207 	d->dv_refcount = 0;
7208 	d->dv_copyID = 0;
7209     }
7210     return d;
7211 }
7212 
7213 /*
7214  * Allocate an empty dict for a return value.
7215  * Returns OK or FAIL.
7216  */
7217     int
7218 rettv_dict_alloc(typval_T *rettv)
7219 {
7220     dict_T	*d = dict_alloc();
7221 
7222     if (d == NULL)
7223 	return FAIL;
7224 
7225     rettv->vval.v_dict = d;
7226     rettv->v_type = VAR_DICT;
7227     ++d->dv_refcount;
7228     return OK;
7229 }
7230 
7231 
7232 /*
7233  * Unreference a Dictionary: decrement the reference count and free it when it
7234  * becomes zero.
7235  */
7236     void
7237 dict_unref(dict_T *d)
7238 {
7239     if (d != NULL && --d->dv_refcount <= 0)
7240 	dict_free(d, TRUE);
7241 }
7242 
7243 /*
7244  * Free a Dictionary, including all non-container items it contains.
7245  * Ignores the reference count.
7246  */
7247     void
7248 dict_free(
7249     dict_T  *d,
7250     int	    recurse)	/* Free Lists and Dictionaries recursively. */
7251 {
7252     int		todo;
7253     hashitem_T	*hi;
7254     dictitem_T	*di;
7255 
7256     /* Remove the dict from the list of dicts for garbage collection. */
7257     if (d->dv_used_prev == NULL)
7258 	first_dict = d->dv_used_next;
7259     else
7260 	d->dv_used_prev->dv_used_next = d->dv_used_next;
7261     if (d->dv_used_next != NULL)
7262 	d->dv_used_next->dv_used_prev = d->dv_used_prev;
7263 
7264     /* Lock the hashtab, we don't want it to resize while freeing items. */
7265     hash_lock(&d->dv_hashtab);
7266     todo = (int)d->dv_hashtab.ht_used;
7267     for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
7268     {
7269 	if (!HASHITEM_EMPTY(hi))
7270 	{
7271 	    /* Remove the item before deleting it, just in case there is
7272 	     * something recursive causing trouble. */
7273 	    di = HI2DI(hi);
7274 	    hash_remove(&d->dv_hashtab, hi);
7275 	    if (recurse || (di->di_tv.v_type != VAR_LIST
7276 					     && di->di_tv.v_type != VAR_DICT))
7277 		clear_tv(&di->di_tv);
7278 	    vim_free(di);
7279 	    --todo;
7280 	}
7281     }
7282     hash_clear(&d->dv_hashtab);
7283     vim_free(d);
7284 }
7285 
7286 /*
7287  * Allocate a Dictionary item.
7288  * The "key" is copied to the new item.
7289  * Note that the value of the item "di_tv" still needs to be initialized!
7290  * Returns NULL when out of memory.
7291  */
7292     dictitem_T *
7293 dictitem_alloc(char_u *key)
7294 {
7295     dictitem_T *di;
7296 
7297     di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key)));
7298     if (di != NULL)
7299     {
7300 	STRCPY(di->di_key, key);
7301 	di->di_flags = DI_FLAGS_ALLOC;
7302     }
7303     return di;
7304 }
7305 
7306 /*
7307  * Make a copy of a Dictionary item.
7308  */
7309     static dictitem_T *
7310 dictitem_copy(dictitem_T *org)
7311 {
7312     dictitem_T *di;
7313 
7314     di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
7315 						      + STRLEN(org->di_key)));
7316     if (di != NULL)
7317     {
7318 	STRCPY(di->di_key, org->di_key);
7319 	di->di_flags = DI_FLAGS_ALLOC;
7320 	copy_tv(&org->di_tv, &di->di_tv);
7321     }
7322     return di;
7323 }
7324 
7325 /*
7326  * Remove item "item" from Dictionary "dict" and free it.
7327  */
7328     static void
7329 dictitem_remove(dict_T *dict, dictitem_T *item)
7330 {
7331     hashitem_T	*hi;
7332 
7333     hi = hash_find(&dict->dv_hashtab, item->di_key);
7334     if (HASHITEM_EMPTY(hi))
7335 	EMSG2(_(e_intern2), "dictitem_remove()");
7336     else
7337 	hash_remove(&dict->dv_hashtab, hi);
7338     dictitem_free(item);
7339 }
7340 
7341 /*
7342  * Free a dict item.  Also clears the value.
7343  */
7344     void
7345 dictitem_free(dictitem_T *item)
7346 {
7347     clear_tv(&item->di_tv);
7348     if (item->di_flags & DI_FLAGS_ALLOC)
7349 	vim_free(item);
7350 }
7351 
7352 /*
7353  * Make a copy of dict "d".  Shallow if "deep" is FALSE.
7354  * The refcount of the new dict is set to 1.
7355  * See item_copy() for "copyID".
7356  * Returns NULL when out of memory.
7357  */
7358     static dict_T *
7359 dict_copy(dict_T *orig, int deep, int copyID)
7360 {
7361     dict_T	*copy;
7362     dictitem_T	*di;
7363     int		todo;
7364     hashitem_T	*hi;
7365 
7366     if (orig == NULL)
7367 	return NULL;
7368 
7369     copy = dict_alloc();
7370     if (copy != NULL)
7371     {
7372 	if (copyID != 0)
7373 	{
7374 	    orig->dv_copyID = copyID;
7375 	    orig->dv_copydict = copy;
7376 	}
7377 	todo = (int)orig->dv_hashtab.ht_used;
7378 	for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
7379 	{
7380 	    if (!HASHITEM_EMPTY(hi))
7381 	    {
7382 		--todo;
7383 
7384 		di = dictitem_alloc(hi->hi_key);
7385 		if (di == NULL)
7386 		    break;
7387 		if (deep)
7388 		{
7389 		    if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep,
7390 							      copyID) == FAIL)
7391 		    {
7392 			vim_free(di);
7393 			break;
7394 		    }
7395 		}
7396 		else
7397 		    copy_tv(&HI2DI(hi)->di_tv, &di->di_tv);
7398 		if (dict_add(copy, di) == FAIL)
7399 		{
7400 		    dictitem_free(di);
7401 		    break;
7402 		}
7403 	    }
7404 	}
7405 
7406 	++copy->dv_refcount;
7407 	if (todo > 0)
7408 	{
7409 	    dict_unref(copy);
7410 	    copy = NULL;
7411 	}
7412     }
7413 
7414     return copy;
7415 }
7416 
7417 /*
7418  * Add item "item" to Dictionary "d".
7419  * Returns FAIL when out of memory and when key already exists.
7420  */
7421     int
7422 dict_add(dict_T *d, dictitem_T *item)
7423 {
7424     return hash_add(&d->dv_hashtab, item->di_key);
7425 }
7426 
7427 /*
7428  * Add a number or string entry to dictionary "d".
7429  * When "str" is NULL use number "nr", otherwise use "str".
7430  * Returns FAIL when out of memory and when key already exists.
7431  */
7432     int
7433 dict_add_nr_str(
7434     dict_T	*d,
7435     char	*key,
7436     long	nr,
7437     char_u	*str)
7438 {
7439     dictitem_T	*item;
7440 
7441     item = dictitem_alloc((char_u *)key);
7442     if (item == NULL)
7443 	return FAIL;
7444     item->di_tv.v_lock = 0;
7445     if (str == NULL)
7446     {
7447 	item->di_tv.v_type = VAR_NUMBER;
7448 	item->di_tv.vval.v_number = nr;
7449     }
7450     else
7451     {
7452 	item->di_tv.v_type = VAR_STRING;
7453 	item->di_tv.vval.v_string = vim_strsave(str);
7454     }
7455     if (dict_add(d, item) == FAIL)
7456     {
7457 	dictitem_free(item);
7458 	return FAIL;
7459     }
7460     return OK;
7461 }
7462 
7463 /*
7464  * Add a list entry to dictionary "d".
7465  * Returns FAIL when out of memory and when key already exists.
7466  */
7467     int
7468 dict_add_list(dict_T *d, char *key, list_T *list)
7469 {
7470     dictitem_T	*item;
7471 
7472     item = dictitem_alloc((char_u *)key);
7473     if (item == NULL)
7474 	return FAIL;
7475     item->di_tv.v_lock = 0;
7476     item->di_tv.v_type = VAR_LIST;
7477     item->di_tv.vval.v_list = list;
7478     if (dict_add(d, item) == FAIL)
7479     {
7480 	dictitem_free(item);
7481 	return FAIL;
7482     }
7483     ++list->lv_refcount;
7484     return OK;
7485 }
7486 
7487 /*
7488  * Get the number of items in a Dictionary.
7489  */
7490     static long
7491 dict_len(dict_T *d)
7492 {
7493     if (d == NULL)
7494 	return 0L;
7495     return (long)d->dv_hashtab.ht_used;
7496 }
7497 
7498 /*
7499  * Find item "key[len]" in Dictionary "d".
7500  * If "len" is negative use strlen(key).
7501  * Returns NULL when not found.
7502  */
7503     dictitem_T *
7504 dict_find(dict_T *d, char_u *key, int len)
7505 {
7506 #define AKEYLEN 200
7507     char_u	buf[AKEYLEN];
7508     char_u	*akey;
7509     char_u	*tofree = NULL;
7510     hashitem_T	*hi;
7511 
7512     if (len < 0)
7513 	akey = key;
7514     else if (len >= AKEYLEN)
7515     {
7516 	tofree = akey = vim_strnsave(key, len);
7517 	if (akey == NULL)
7518 	    return NULL;
7519     }
7520     else
7521     {
7522 	/* Avoid a malloc/free by using buf[]. */
7523 	vim_strncpy(buf, key, len);
7524 	akey = buf;
7525     }
7526 
7527     hi = hash_find(&d->dv_hashtab, akey);
7528     vim_free(tofree);
7529     if (HASHITEM_EMPTY(hi))
7530 	return NULL;
7531     return HI2DI(hi);
7532 }
7533 
7534 /*
7535  * Get a string item from a dictionary.
7536  * When "save" is TRUE allocate memory for it.
7537  * Returns NULL if the entry doesn't exist or out of memory.
7538  */
7539     char_u *
7540 get_dict_string(dict_T *d, char_u *key, int save)
7541 {
7542     dictitem_T	*di;
7543     char_u	*s;
7544 
7545     di = dict_find(d, key, -1);
7546     if (di == NULL)
7547 	return NULL;
7548     s = get_tv_string(&di->di_tv);
7549     if (save && s != NULL)
7550 	s = vim_strsave(s);
7551     return s;
7552 }
7553 
7554 /*
7555  * Get a number item from a dictionary.
7556  * Returns 0 if the entry doesn't exist.
7557  */
7558     long
7559 get_dict_number(dict_T *d, char_u *key)
7560 {
7561     dictitem_T	*di;
7562 
7563     di = dict_find(d, key, -1);
7564     if (di == NULL)
7565 	return 0;
7566     return get_tv_number(&di->di_tv);
7567 }
7568 
7569 /*
7570  * Return an allocated string with the string representation of a Dictionary.
7571  * May return NULL.
7572  */
7573     static char_u *
7574 dict2string(typval_T *tv, int copyID)
7575 {
7576     garray_T	ga;
7577     int		first = TRUE;
7578     char_u	*tofree;
7579     char_u	numbuf[NUMBUFLEN];
7580     hashitem_T	*hi;
7581     char_u	*s;
7582     dict_T	*d;
7583     int		todo;
7584 
7585     if ((d = tv->vval.v_dict) == NULL)
7586 	return NULL;
7587     ga_init2(&ga, (int)sizeof(char), 80);
7588     ga_append(&ga, '{');
7589 
7590     todo = (int)d->dv_hashtab.ht_used;
7591     for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
7592     {
7593 	if (!HASHITEM_EMPTY(hi))
7594 	{
7595 	    --todo;
7596 
7597 	    if (first)
7598 		first = FALSE;
7599 	    else
7600 		ga_concat(&ga, (char_u *)", ");
7601 
7602 	    tofree = string_quote(hi->hi_key, FALSE);
7603 	    if (tofree != NULL)
7604 	    {
7605 		ga_concat(&ga, tofree);
7606 		vim_free(tofree);
7607 	    }
7608 	    ga_concat(&ga, (char_u *)": ");
7609 	    s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
7610 	    if (s != NULL)
7611 		ga_concat(&ga, s);
7612 	    vim_free(tofree);
7613 	    if (s == NULL || did_echo_string_emsg)
7614 		break;
7615 	    line_breakcheck();
7616 
7617 	}
7618     }
7619     if (todo > 0)
7620     {
7621 	vim_free(ga.ga_data);
7622 	return NULL;
7623     }
7624 
7625     ga_append(&ga, '}');
7626     ga_append(&ga, NUL);
7627     return (char_u *)ga.ga_data;
7628 }
7629 
7630 /*
7631  * Allocate a variable for a Dictionary and fill it from "*arg".
7632  * Return OK or FAIL.  Returns NOTDONE for {expr}.
7633  */
7634     static int
7635 get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
7636 {
7637     dict_T	*d = NULL;
7638     typval_T	tvkey;
7639     typval_T	tv;
7640     char_u	*key = NULL;
7641     dictitem_T	*item;
7642     char_u	*start = skipwhite(*arg + 1);
7643     char_u	buf[NUMBUFLEN];
7644 
7645     /*
7646      * First check if it's not a curly-braces thing: {expr}.
7647      * Must do this without evaluating, otherwise a function may be called
7648      * twice.  Unfortunately this means we need to call eval1() twice for the
7649      * first item.
7650      * But {} is an empty Dictionary.
7651      */
7652     if (*start != '}')
7653     {
7654 	if (eval1(&start, &tv, FALSE) == FAIL)	/* recursive! */
7655 	    return FAIL;
7656 	if (*start == '}')
7657 	    return NOTDONE;
7658     }
7659 
7660     if (evaluate)
7661     {
7662 	d = dict_alloc();
7663 	if (d == NULL)
7664 	    return FAIL;
7665     }
7666     tvkey.v_type = VAR_UNKNOWN;
7667     tv.v_type = VAR_UNKNOWN;
7668 
7669     *arg = skipwhite(*arg + 1);
7670     while (**arg != '}' && **arg != NUL)
7671     {
7672 	if (eval1(arg, &tvkey, evaluate) == FAIL)	/* recursive! */
7673 	    goto failret;
7674 	if (**arg != ':')
7675 	{
7676 	    EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg);
7677 	    clear_tv(&tvkey);
7678 	    goto failret;
7679 	}
7680 	if (evaluate)
7681 	{
7682 	    key = get_tv_string_buf_chk(&tvkey, buf);
7683 	    if (key == NULL || *key == NUL)
7684 	    {
7685 		/* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
7686 		if (key != NULL)
7687 		    EMSG(_(e_emptykey));
7688 		clear_tv(&tvkey);
7689 		goto failret;
7690 	    }
7691 	}
7692 
7693 	*arg = skipwhite(*arg + 1);
7694 	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
7695 	{
7696 	    if (evaluate)
7697 		clear_tv(&tvkey);
7698 	    goto failret;
7699 	}
7700 	if (evaluate)
7701 	{
7702 	    item = dict_find(d, key, -1);
7703 	    if (item != NULL)
7704 	    {
7705 		EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key);
7706 		clear_tv(&tvkey);
7707 		clear_tv(&tv);
7708 		goto failret;
7709 	    }
7710 	    item = dictitem_alloc(key);
7711 	    clear_tv(&tvkey);
7712 	    if (item != NULL)
7713 	    {
7714 		item->di_tv = tv;
7715 		item->di_tv.v_lock = 0;
7716 		if (dict_add(d, item) == FAIL)
7717 		    dictitem_free(item);
7718 	    }
7719 	}
7720 
7721 	if (**arg == '}')
7722 	    break;
7723 	if (**arg != ',')
7724 	{
7725 	    EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg);
7726 	    goto failret;
7727 	}
7728 	*arg = skipwhite(*arg + 1);
7729     }
7730 
7731     if (**arg != '}')
7732     {
7733 	EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg);
7734 failret:
7735 	if (evaluate)
7736 	    dict_free(d, TRUE);
7737 	return FAIL;
7738     }
7739 
7740     *arg = skipwhite(*arg + 1);
7741     if (evaluate)
7742     {
7743 	rettv->v_type = VAR_DICT;
7744 	rettv->vval.v_dict = d;
7745 	++d->dv_refcount;
7746     }
7747 
7748     return OK;
7749 }
7750 
7751 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
7752 #endif
7753 
7754     static char *
7755 get_var_special_name(int nr)
7756 {
7757     switch (nr)
7758     {
7759 	case VVAL_FALSE: return "v:false";
7760 	case VVAL_TRUE:  return "v:true";
7761 	case VVAL_NONE:  return "v:none";
7762 	case VVAL_NULL:  return "v:null";
7763     }
7764     EMSG2(_(e_intern2), "get_var_special_name()");
7765     return "42";
7766 }
7767 
7768 /*
7769  * Return a string with the string representation of a variable.
7770  * If the memory is allocated "tofree" is set to it, otherwise NULL.
7771  * "numbuf" is used for a number.
7772  * Does not put quotes around strings, as ":echo" displays values.
7773  * When "copyID" is not NULL replace recursive lists and dicts with "...".
7774  * May return NULL.
7775  */
7776     static char_u *
7777 echo_string(
7778     typval_T	*tv,
7779     char_u	**tofree,
7780     char_u	*numbuf,
7781     int		copyID)
7782 {
7783     static int	recurse = 0;
7784     char_u	*r = NULL;
7785 
7786     if (recurse >= DICT_MAXNEST)
7787     {
7788 	if (!did_echo_string_emsg)
7789 	{
7790 	    /* Only give this message once for a recursive call to avoid
7791 	     * flooding the user with errors.  And stop iterating over lists
7792 	     * and dicts. */
7793 	    did_echo_string_emsg = TRUE;
7794 	    EMSG(_("E724: variable nested too deep for displaying"));
7795 	}
7796 	*tofree = NULL;
7797 	return (char_u *)"{E724}";
7798     }
7799     ++recurse;
7800 
7801     switch (tv->v_type)
7802     {
7803 	case VAR_FUNC:
7804 	    *tofree = NULL;
7805 	    r = tv->vval.v_string;
7806 	    break;
7807 
7808 	case VAR_PARTIAL:
7809 	    *tofree = NULL;
7810 	    /* TODO: arguments */
7811 	    r = tv->vval.v_partial == NULL ? NULL : tv->vval.v_partial->pt_name;
7812 	    break;
7813 
7814 	case VAR_LIST:
7815 	    if (tv->vval.v_list == NULL)
7816 	    {
7817 		*tofree = NULL;
7818 		r = NULL;
7819 	    }
7820 	    else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID)
7821 	    {
7822 		*tofree = NULL;
7823 		r = (char_u *)"[...]";
7824 	    }
7825 	    else
7826 	    {
7827 		tv->vval.v_list->lv_copyID = copyID;
7828 		*tofree = list2string(tv, copyID);
7829 		r = *tofree;
7830 	    }
7831 	    break;
7832 
7833 	case VAR_DICT:
7834 	    if (tv->vval.v_dict == NULL)
7835 	    {
7836 		*tofree = NULL;
7837 		r = NULL;
7838 	    }
7839 	    else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID)
7840 	    {
7841 		*tofree = NULL;
7842 		r = (char_u *)"{...}";
7843 	    }
7844 	    else
7845 	    {
7846 		tv->vval.v_dict->dv_copyID = copyID;
7847 		*tofree = dict2string(tv, copyID);
7848 		r = *tofree;
7849 	    }
7850 	    break;
7851 
7852 	case VAR_STRING:
7853 	case VAR_NUMBER:
7854 	case VAR_UNKNOWN:
7855 	case VAR_JOB:
7856 	case VAR_CHANNEL:
7857 	    *tofree = NULL;
7858 	    r = get_tv_string_buf(tv, numbuf);
7859 	    break;
7860 
7861 	case VAR_FLOAT:
7862 #ifdef FEAT_FLOAT
7863 	    *tofree = NULL;
7864 	    vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float);
7865 	    r = numbuf;
7866 	    break;
7867 #endif
7868 
7869 	case VAR_SPECIAL:
7870 	    *tofree = NULL;
7871 	    r = (char_u *)get_var_special_name(tv->vval.v_number);
7872 	    break;
7873     }
7874 
7875     if (--recurse == 0)
7876 	did_echo_string_emsg = FALSE;
7877     return r;
7878 }
7879 
7880 /*
7881  * Return a string with the string representation of a variable.
7882  * If the memory is allocated "tofree" is set to it, otherwise NULL.
7883  * "numbuf" is used for a number.
7884  * Puts quotes around strings, so that they can be parsed back by eval().
7885  * May return NULL.
7886  */
7887     static char_u *
7888 tv2string(
7889     typval_T	*tv,
7890     char_u	**tofree,
7891     char_u	*numbuf,
7892     int		copyID)
7893 {
7894     switch (tv->v_type)
7895     {
7896 	case VAR_FUNC:
7897 	    *tofree = string_quote(tv->vval.v_string, TRUE);
7898 	    return *tofree;
7899 	case VAR_PARTIAL:
7900 	    {
7901 		partial_T   *pt = tv->vval.v_partial;
7902 		char_u	    *fname = string_quote(pt == NULL ? NULL
7903 							: pt->pt_name, FALSE);
7904 		garray_T    ga;
7905 		int	    i;
7906 		char_u	    *tf;
7907 
7908 		ga_init2(&ga, 1, 100);
7909 		ga_concat(&ga, (char_u *)"function(");
7910 		if (fname != NULL)
7911 		{
7912 		    ga_concat(&ga, fname);
7913 		    vim_free(fname);
7914 		}
7915 		if (pt != NULL && pt->pt_argc > 0)
7916 		{
7917 		    ga_concat(&ga, (char_u *)", [");
7918 		    for (i = 0; i < pt->pt_argc; ++i)
7919 		    {
7920 			if (i > 0)
7921 			    ga_concat(&ga, (char_u *)", ");
7922 			ga_concat(&ga,
7923 			     tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
7924 			vim_free(tf);
7925 		    }
7926 		    ga_concat(&ga, (char_u *)"]");
7927 		}
7928 		if (pt != NULL && pt->pt_dict != NULL)
7929 		{
7930 		    typval_T dtv;
7931 
7932 		    ga_concat(&ga, (char_u *)", ");
7933 		    dtv.v_type = VAR_DICT;
7934 		    dtv.vval.v_dict = pt->pt_dict;
7935 		    ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
7936 		    vim_free(tf);
7937 		}
7938 		ga_concat(&ga, (char_u *)")");
7939 
7940 		*tofree = ga.ga_data;
7941 		return *tofree;
7942 	    }
7943 	case VAR_STRING:
7944 	    *tofree = string_quote(tv->vval.v_string, FALSE);
7945 	    return *tofree;
7946 	case VAR_FLOAT:
7947 #ifdef FEAT_FLOAT
7948 	    *tofree = NULL;
7949 	    vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float);
7950 	    return numbuf;
7951 #endif
7952 	case VAR_NUMBER:
7953 	case VAR_LIST:
7954 	case VAR_DICT:
7955 	case VAR_SPECIAL:
7956 	case VAR_JOB:
7957 	case VAR_CHANNEL:
7958 	case VAR_UNKNOWN:
7959 	    break;
7960     }
7961     return echo_string(tv, tofree, numbuf, copyID);
7962 }
7963 
7964 /*
7965  * Return string "str" in ' quotes, doubling ' characters.
7966  * If "str" is NULL an empty string is assumed.
7967  * If "function" is TRUE make it function('string').
7968  */
7969     static char_u *
7970 string_quote(char_u *str, int function)
7971 {
7972     unsigned	len;
7973     char_u	*p, *r, *s;
7974 
7975     len = (function ? 13 : 3);
7976     if (str != NULL)
7977     {
7978 	len += (unsigned)STRLEN(str);
7979 	for (p = str; *p != NUL; mb_ptr_adv(p))
7980 	    if (*p == '\'')
7981 		++len;
7982     }
7983     s = r = alloc(len);
7984     if (r != NULL)
7985     {
7986 	if (function)
7987 	{
7988 	    STRCPY(r, "function('");
7989 	    r += 10;
7990 	}
7991 	else
7992 	    *r++ = '\'';
7993 	if (str != NULL)
7994 	    for (p = str; *p != NUL; )
7995 	    {
7996 		if (*p == '\'')
7997 		    *r++ = '\'';
7998 		MB_COPY_CHAR(p, r);
7999 	    }
8000 	*r++ = '\'';
8001 	if (function)
8002 	    *r++ = ')';
8003 	*r++ = NUL;
8004     }
8005     return s;
8006 }
8007 
8008 #if defined(FEAT_FLOAT) || defined(PROTO)
8009 /*
8010  * Convert the string "text" to a floating point number.
8011  * This uses strtod().  setlocale(LC_NUMERIC, "C") has been used to make sure
8012  * this always uses a decimal point.
8013  * Returns the length of the text that was consumed.
8014  */
8015     int
8016 string2float(
8017     char_u	*text,
8018     float_T	*value)	    /* result stored here */
8019 {
8020     char	*s = (char *)text;
8021     float_T	f;
8022 
8023     f = strtod(s, &s);
8024     *value = f;
8025     return (int)((char_u *)s - text);
8026 }
8027 #endif
8028 
8029 /*
8030  * Get the value of an environment variable.
8031  * "arg" is pointing to the '$'.  It is advanced to after the name.
8032  * If the environment variable was not set, silently assume it is empty.
8033  * Return FAIL if the name is invalid.
8034  */
8035     static int
8036 get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
8037 {
8038     char_u	*string = NULL;
8039     int		len;
8040     int		cc;
8041     char_u	*name;
8042     int		mustfree = FALSE;
8043 
8044     ++*arg;
8045     name = *arg;
8046     len = get_env_len(arg);
8047     if (evaluate)
8048     {
8049 	if (len == 0)
8050 	    return FAIL; /* invalid empty name */
8051 
8052 	cc = name[len];
8053 	name[len] = NUL;
8054 	/* first try vim_getenv(), fast for normal environment vars */
8055 	string = vim_getenv(name, &mustfree);
8056 	if (string != NULL && *string != NUL)
8057 	{
8058 	    if (!mustfree)
8059 		string = vim_strsave(string);
8060 	}
8061 	else
8062 	{
8063 	    if (mustfree)
8064 		vim_free(string);
8065 
8066 	    /* next try expanding things like $VIM and ${HOME} */
8067 	    string = expand_env_save(name - 1);
8068 	    if (string != NULL && *string == '$')
8069 	    {
8070 		vim_free(string);
8071 		string = NULL;
8072 	    }
8073 	}
8074 	name[len] = cc;
8075 
8076 	rettv->v_type = VAR_STRING;
8077 	rettv->vval.v_string = string;
8078     }
8079 
8080     return OK;
8081 }
8082 
8083 /*
8084  * Array with names and number of arguments of all internal functions
8085  * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH!
8086  */
8087 static struct fst
8088 {
8089     char	*f_name;	/* function name */
8090     char	f_min_argc;	/* minimal number of arguments */
8091     char	f_max_argc;	/* maximal number of arguments */
8092     void	(*f_func)(typval_T *args, typval_T *rvar);
8093 				/* implementation of function */
8094 } functions[] =
8095 {
8096 #ifdef FEAT_FLOAT
8097     {"abs",		1, 1, f_abs},
8098     {"acos",		1, 1, f_acos},	/* WJMc */
8099 #endif
8100     {"add",		2, 2, f_add},
8101     {"alloc_fail",	3, 3, f_alloc_fail},
8102     {"and",		2, 2, f_and},
8103     {"append",		2, 2, f_append},
8104     {"argc",		0, 0, f_argc},
8105     {"argidx",		0, 0, f_argidx},
8106     {"arglistid",	0, 2, f_arglistid},
8107     {"argv",		0, 1, f_argv},
8108 #ifdef FEAT_FLOAT
8109     {"asin",		1, 1, f_asin},	/* WJMc */
8110 #endif
8111     {"assert_equal",	2, 3, f_assert_equal},
8112     {"assert_exception", 1, 2, f_assert_exception},
8113     {"assert_fails",	1, 2, f_assert_fails},
8114     {"assert_false",	1, 2, f_assert_false},
8115     {"assert_true",	1, 2, f_assert_true},
8116 #ifdef FEAT_FLOAT
8117     {"atan",		1, 1, f_atan},
8118     {"atan2",		2, 2, f_atan2},
8119 #endif
8120     {"browse",		4, 4, f_browse},
8121     {"browsedir",	2, 2, f_browsedir},
8122     {"bufexists",	1, 1, f_bufexists},
8123     {"buffer_exists",	1, 1, f_bufexists},	/* obsolete */
8124     {"buffer_name",	1, 1, f_bufname},	/* obsolete */
8125     {"buffer_number",	1, 1, f_bufnr},		/* obsolete */
8126     {"buflisted",	1, 1, f_buflisted},
8127     {"bufloaded",	1, 1, f_bufloaded},
8128     {"bufname",		1, 1, f_bufname},
8129     {"bufnr",		1, 2, f_bufnr},
8130     {"bufwinnr",	1, 1, f_bufwinnr},
8131     {"byte2line",	1, 1, f_byte2line},
8132     {"byteidx",		2, 2, f_byteidx},
8133     {"byteidxcomp",	2, 2, f_byteidxcomp},
8134     {"call",		2, 3, f_call},
8135 #ifdef FEAT_FLOAT
8136     {"ceil",		1, 1, f_ceil},
8137 #endif
8138 #ifdef FEAT_JOB_CHANNEL
8139     {"ch_close",	1, 1, f_ch_close},
8140     {"ch_evalexpr",	2, 3, f_ch_evalexpr},
8141     {"ch_evalraw",	2, 3, f_ch_evalraw},
8142     {"ch_getbufnr",	2, 2, f_ch_getbufnr},
8143     {"ch_getjob",	1, 1, f_ch_getjob},
8144     {"ch_log",		1, 2, f_ch_log},
8145     {"ch_logfile",	1, 2, f_ch_logfile},
8146     {"ch_open",		1, 2, f_ch_open},
8147     {"ch_read",		1, 2, f_ch_read},
8148     {"ch_readraw",	1, 2, f_ch_readraw},
8149     {"ch_sendexpr",	2, 3, f_ch_sendexpr},
8150     {"ch_sendraw",	2, 3, f_ch_sendraw},
8151     {"ch_setoptions",	2, 2, f_ch_setoptions},
8152     {"ch_status",	1, 1, f_ch_status},
8153 #endif
8154     {"changenr",	0, 0, f_changenr},
8155     {"char2nr",		1, 2, f_char2nr},
8156     {"cindent",		1, 1, f_cindent},
8157     {"clearmatches",	0, 0, f_clearmatches},
8158     {"col",		1, 1, f_col},
8159 #if defined(FEAT_INS_EXPAND)
8160     {"complete",	2, 2, f_complete},
8161     {"complete_add",	1, 1, f_complete_add},
8162     {"complete_check",	0, 0, f_complete_check},
8163 #endif
8164     {"confirm",		1, 4, f_confirm},
8165     {"copy",		1, 1, f_copy},
8166 #ifdef FEAT_FLOAT
8167     {"cos",		1, 1, f_cos},
8168     {"cosh",		1, 1, f_cosh},
8169 #endif
8170     {"count",		2, 4, f_count},
8171     {"cscope_connection",0,3, f_cscope_connection},
8172     {"cursor",		1, 3, f_cursor},
8173     {"deepcopy",	1, 2, f_deepcopy},
8174     {"delete",		1, 2, f_delete},
8175     {"did_filetype",	0, 0, f_did_filetype},
8176     {"diff_filler",	1, 1, f_diff_filler},
8177     {"diff_hlID",	2, 2, f_diff_hlID},
8178     {"disable_char_avail_for_testing", 1, 1, f_disable_char_avail_for_testing},
8179     {"empty",		1, 1, f_empty},
8180     {"escape",		2, 2, f_escape},
8181     {"eval",		1, 1, f_eval},
8182     {"eventhandler",	0, 0, f_eventhandler},
8183     {"executable",	1, 1, f_executable},
8184     {"exepath",		1, 1, f_exepath},
8185     {"exists",		1, 1, f_exists},
8186 #ifdef FEAT_FLOAT
8187     {"exp",		1, 1, f_exp},
8188 #endif
8189     {"expand",		1, 3, f_expand},
8190     {"extend",		2, 3, f_extend},
8191     {"feedkeys",	1, 2, f_feedkeys},
8192     {"file_readable",	1, 1, f_filereadable},	/* obsolete */
8193     {"filereadable",	1, 1, f_filereadable},
8194     {"filewritable",	1, 1, f_filewritable},
8195     {"filter",		2, 2, f_filter},
8196     {"finddir",		1, 3, f_finddir},
8197     {"findfile",	1, 3, f_findfile},
8198 #ifdef FEAT_FLOAT
8199     {"float2nr",	1, 1, f_float2nr},
8200     {"floor",		1, 1, f_floor},
8201     {"fmod",		2, 2, f_fmod},
8202 #endif
8203     {"fnameescape",	1, 1, f_fnameescape},
8204     {"fnamemodify",	2, 2, f_fnamemodify},
8205     {"foldclosed",	1, 1, f_foldclosed},
8206     {"foldclosedend",	1, 1, f_foldclosedend},
8207     {"foldlevel",	1, 1, f_foldlevel},
8208     {"foldtext",	0, 0, f_foldtext},
8209     {"foldtextresult",	1, 1, f_foldtextresult},
8210     {"foreground",	0, 0, f_foreground},
8211     {"function",	1, 3, f_function},
8212     {"garbagecollect",	0, 1, f_garbagecollect},
8213     {"get",		2, 3, f_get},
8214     {"getbufline",	2, 3, f_getbufline},
8215     {"getbufvar",	2, 3, f_getbufvar},
8216     {"getchar",		0, 1, f_getchar},
8217     {"getcharmod",	0, 0, f_getcharmod},
8218     {"getcharsearch",	0, 0, f_getcharsearch},
8219     {"getcmdline",	0, 0, f_getcmdline},
8220     {"getcmdpos",	0, 0, f_getcmdpos},
8221     {"getcmdtype",	0, 0, f_getcmdtype},
8222     {"getcmdwintype",	0, 0, f_getcmdwintype},
8223     {"getcurpos",	0, 0, f_getcurpos},
8224     {"getcwd",		0, 2, f_getcwd},
8225     {"getfontname",	0, 1, f_getfontname},
8226     {"getfperm",	1, 1, f_getfperm},
8227     {"getfsize",	1, 1, f_getfsize},
8228     {"getftime",	1, 1, f_getftime},
8229     {"getftype",	1, 1, f_getftype},
8230     {"getline",		1, 2, f_getline},
8231     {"getloclist",	1, 1, f_getqflist},
8232     {"getmatches",	0, 0, f_getmatches},
8233     {"getpid",		0, 0, f_getpid},
8234     {"getpos",		1, 1, f_getpos},
8235     {"getqflist",	0, 0, f_getqflist},
8236     {"getreg",		0, 3, f_getreg},
8237     {"getregtype",	0, 1, f_getregtype},
8238     {"gettabvar",	2, 3, f_gettabvar},
8239     {"gettabwinvar",	3, 4, f_gettabwinvar},
8240     {"getwinposx",	0, 0, f_getwinposx},
8241     {"getwinposy",	0, 0, f_getwinposy},
8242     {"getwinvar",	2, 3, f_getwinvar},
8243     {"glob",		1, 4, f_glob},
8244     {"glob2regpat",	1, 1, f_glob2regpat},
8245     {"globpath",	2, 5, f_globpath},
8246     {"has",		1, 1, f_has},
8247     {"has_key",		2, 2, f_has_key},
8248     {"haslocaldir",	0, 2, f_haslocaldir},
8249     {"hasmapto",	1, 3, f_hasmapto},
8250     {"highlightID",	1, 1, f_hlID},		/* obsolete */
8251     {"highlight_exists",1, 1, f_hlexists},	/* obsolete */
8252     {"histadd",		2, 2, f_histadd},
8253     {"histdel",		1, 2, f_histdel},
8254     {"histget",		1, 2, f_histget},
8255     {"histnr",		1, 1, f_histnr},
8256     {"hlID",		1, 1, f_hlID},
8257     {"hlexists",	1, 1, f_hlexists},
8258     {"hostname",	0, 0, f_hostname},
8259     {"iconv",		3, 3, f_iconv},
8260     {"indent",		1, 1, f_indent},
8261     {"index",		2, 4, f_index},
8262     {"input",		1, 3, f_input},
8263     {"inputdialog",	1, 3, f_inputdialog},
8264     {"inputlist",	1, 1, f_inputlist},
8265     {"inputrestore",	0, 0, f_inputrestore},
8266     {"inputsave",	0, 0, f_inputsave},
8267     {"inputsecret",	1, 2, f_inputsecret},
8268     {"insert",		2, 3, f_insert},
8269     {"invert",		1, 1, f_invert},
8270     {"isdirectory",	1, 1, f_isdirectory},
8271     {"islocked",	1, 1, f_islocked},
8272 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
8273     {"isnan",		1, 1, f_isnan},
8274 #endif
8275     {"items",		1, 1, f_items},
8276 #ifdef FEAT_JOB_CHANNEL
8277     {"job_getchannel",	1, 1, f_job_getchannel},
8278     {"job_info",	1, 1, f_job_info},
8279     {"job_setoptions",	2, 2, f_job_setoptions},
8280     {"job_start",	1, 2, f_job_start},
8281     {"job_status",	1, 1, f_job_status},
8282     {"job_stop",	1, 2, f_job_stop},
8283 #endif
8284     {"join",		1, 2, f_join},
8285     {"js_decode",	1, 1, f_js_decode},
8286     {"js_encode",	1, 1, f_js_encode},
8287     {"json_decode",	1, 1, f_json_decode},
8288     {"json_encode",	1, 1, f_json_encode},
8289     {"keys",		1, 1, f_keys},
8290     {"last_buffer_nr",	0, 0, f_last_buffer_nr},/* obsolete */
8291     {"len",		1, 1, f_len},
8292     {"libcall",		3, 3, f_libcall},
8293     {"libcallnr",	3, 3, f_libcallnr},
8294     {"line",		1, 1, f_line},
8295     {"line2byte",	1, 1, f_line2byte},
8296     {"lispindent",	1, 1, f_lispindent},
8297     {"localtime",	0, 0, f_localtime},
8298 #ifdef FEAT_FLOAT
8299     {"log",		1, 1, f_log},
8300     {"log10",		1, 1, f_log10},
8301 #endif
8302 #ifdef FEAT_LUA
8303     {"luaeval",		1, 2, f_luaeval},
8304 #endif
8305     {"map",		2, 2, f_map},
8306     {"maparg",		1, 4, f_maparg},
8307     {"mapcheck",	1, 3, f_mapcheck},
8308     {"match",		2, 4, f_match},
8309     {"matchadd",	2, 5, f_matchadd},
8310     {"matchaddpos",	2, 5, f_matchaddpos},
8311     {"matcharg",	1, 1, f_matcharg},
8312     {"matchdelete",	1, 1, f_matchdelete},
8313     {"matchend",	2, 4, f_matchend},
8314     {"matchlist",	2, 4, f_matchlist},
8315     {"matchstr",	2, 4, f_matchstr},
8316     {"max",		1, 1, f_max},
8317     {"min",		1, 1, f_min},
8318 #ifdef vim_mkdir
8319     {"mkdir",		1, 3, f_mkdir},
8320 #endif
8321     {"mode",		0, 1, f_mode},
8322 #ifdef FEAT_MZSCHEME
8323     {"mzeval",		1, 1, f_mzeval},
8324 #endif
8325     {"nextnonblank",	1, 1, f_nextnonblank},
8326     {"nr2char",		1, 2, f_nr2char},
8327     {"or",		2, 2, f_or},
8328     {"pathshorten",	1, 1, f_pathshorten},
8329 #ifdef FEAT_PERL
8330     {"perleval",	1, 1, f_perleval},
8331 #endif
8332 #ifdef FEAT_FLOAT
8333     {"pow",		2, 2, f_pow},
8334 #endif
8335     {"prevnonblank",	1, 1, f_prevnonblank},
8336     {"printf",		2, 19, f_printf},
8337     {"pumvisible",	0, 0, f_pumvisible},
8338 #ifdef FEAT_PYTHON3
8339     {"py3eval",		1, 1, f_py3eval},
8340 #endif
8341 #ifdef FEAT_PYTHON
8342     {"pyeval",		1, 1, f_pyeval},
8343 #endif
8344     {"range",		1, 3, f_range},
8345     {"readfile",	1, 3, f_readfile},
8346     {"reltime",		0, 2, f_reltime},
8347 #ifdef FEAT_FLOAT
8348     {"reltimefloat",	1, 1, f_reltimefloat},
8349 #endif
8350     {"reltimestr",	1, 1, f_reltimestr},
8351     {"remote_expr",	2, 3, f_remote_expr},
8352     {"remote_foreground", 1, 1, f_remote_foreground},
8353     {"remote_peek",	1, 2, f_remote_peek},
8354     {"remote_read",	1, 1, f_remote_read},
8355     {"remote_send",	2, 3, f_remote_send},
8356     {"remove",		2, 3, f_remove},
8357     {"rename",		2, 2, f_rename},
8358     {"repeat",		2, 2, f_repeat},
8359     {"resolve",		1, 1, f_resolve},
8360     {"reverse",		1, 1, f_reverse},
8361 #ifdef FEAT_FLOAT
8362     {"round",		1, 1, f_round},
8363 #endif
8364     {"screenattr",	2, 2, f_screenattr},
8365     {"screenchar",	2, 2, f_screenchar},
8366     {"screencol",	0, 0, f_screencol},
8367     {"screenrow",	0, 0, f_screenrow},
8368     {"search",		1, 4, f_search},
8369     {"searchdecl",	1, 3, f_searchdecl},
8370     {"searchpair",	3, 7, f_searchpair},
8371     {"searchpairpos",	3, 7, f_searchpairpos},
8372     {"searchpos",	1, 4, f_searchpos},
8373     {"server2client",	2, 2, f_server2client},
8374     {"serverlist",	0, 0, f_serverlist},
8375     {"setbufvar",	3, 3, f_setbufvar},
8376     {"setcharsearch",	1, 1, f_setcharsearch},
8377     {"setcmdpos",	1, 1, f_setcmdpos},
8378     {"setfperm",	2, 2, f_setfperm},
8379     {"setline",		2, 2, f_setline},
8380     {"setloclist",	2, 3, f_setloclist},
8381     {"setmatches",	1, 1, f_setmatches},
8382     {"setpos",		2, 2, f_setpos},
8383     {"setqflist",	1, 2, f_setqflist},
8384     {"setreg",		2, 3, f_setreg},
8385     {"settabvar",	3, 3, f_settabvar},
8386     {"settabwinvar",	4, 4, f_settabwinvar},
8387     {"setwinvar",	3, 3, f_setwinvar},
8388 #ifdef FEAT_CRYPT
8389     {"sha256",		1, 1, f_sha256},
8390 #endif
8391     {"shellescape",	1, 2, f_shellescape},
8392     {"shiftwidth",	0, 0, f_shiftwidth},
8393     {"simplify",	1, 1, f_simplify},
8394 #ifdef FEAT_FLOAT
8395     {"sin",		1, 1, f_sin},
8396     {"sinh",		1, 1, f_sinh},
8397 #endif
8398     {"sort",		1, 3, f_sort},
8399     {"soundfold",	1, 1, f_soundfold},
8400     {"spellbadword",	0, 1, f_spellbadword},
8401     {"spellsuggest",	1, 3, f_spellsuggest},
8402     {"split",		1, 3, f_split},
8403 #ifdef FEAT_FLOAT
8404     {"sqrt",		1, 1, f_sqrt},
8405     {"str2float",	1, 1, f_str2float},
8406 #endif
8407     {"str2nr",		1, 2, f_str2nr},
8408     {"strchars",	1, 2, f_strchars},
8409     {"strdisplaywidth",	1, 2, f_strdisplaywidth},
8410 #ifdef HAVE_STRFTIME
8411     {"strftime",	1, 2, f_strftime},
8412 #endif
8413     {"stridx",		2, 3, f_stridx},
8414     {"string",		1, 1, f_string},
8415     {"strlen",		1, 1, f_strlen},
8416     {"strpart",		2, 3, f_strpart},
8417     {"strridx",		2, 3, f_strridx},
8418     {"strtrans",	1, 1, f_strtrans},
8419     {"strwidth",	1, 1, f_strwidth},
8420     {"submatch",	1, 2, f_submatch},
8421     {"substitute",	4, 4, f_substitute},
8422     {"synID",		3, 3, f_synID},
8423     {"synIDattr",	2, 3, f_synIDattr},
8424     {"synIDtrans",	1, 1, f_synIDtrans},
8425     {"synconcealed",	2, 2, f_synconcealed},
8426     {"synstack",	2, 2, f_synstack},
8427     {"system",		1, 2, f_system},
8428     {"systemlist",	1, 2, f_systemlist},
8429     {"tabpagebuflist",	0, 1, f_tabpagebuflist},
8430     {"tabpagenr",	0, 1, f_tabpagenr},
8431     {"tabpagewinnr",	1, 2, f_tabpagewinnr},
8432     {"tagfiles",	0, 0, f_tagfiles},
8433     {"taglist",		1, 1, f_taglist},
8434 #ifdef FEAT_FLOAT
8435     {"tan",		1, 1, f_tan},
8436     {"tanh",		1, 1, f_tanh},
8437 #endif
8438     {"tempname",	0, 0, f_tempname},
8439     {"test",		1, 1, f_test},
8440 #ifdef FEAT_TIMERS
8441     {"timer_start",	2, 3, f_timer_start},
8442     {"timer_stop",	1, 1, f_timer_stop},
8443 #endif
8444     {"tolower",		1, 1, f_tolower},
8445     {"toupper",		1, 1, f_toupper},
8446     {"tr",		3, 3, f_tr},
8447 #ifdef FEAT_FLOAT
8448     {"trunc",		1, 1, f_trunc},
8449 #endif
8450     {"type",		1, 1, f_type},
8451     {"undofile",	1, 1, f_undofile},
8452     {"undotree",	0, 0, f_undotree},
8453     {"uniq",		1, 3, f_uniq},
8454     {"values",		1, 1, f_values},
8455     {"virtcol",		1, 1, f_virtcol},
8456     {"visualmode",	0, 1, f_visualmode},
8457     {"wildmenumode",	0, 0, f_wildmenumode},
8458     {"win_findbuf",	1, 1, f_win_findbuf},
8459     {"win_getid",	0, 2, f_win_getid},
8460     {"win_gotoid",	1, 1, f_win_gotoid},
8461     {"win_id2tabwin",	1, 1, f_win_id2tabwin},
8462     {"win_id2win",	1, 1, f_win_id2win},
8463     {"winbufnr",	1, 1, f_winbufnr},
8464     {"wincol",		0, 0, f_wincol},
8465     {"winheight",	1, 1, f_winheight},
8466     {"winline",		0, 0, f_winline},
8467     {"winnr",		0, 1, f_winnr},
8468     {"winrestcmd",	0, 0, f_winrestcmd},
8469     {"winrestview",	1, 1, f_winrestview},
8470     {"winsaveview",	0, 0, f_winsaveview},
8471     {"winwidth",	1, 1, f_winwidth},
8472     {"wordcount",	0, 0, f_wordcount},
8473     {"writefile",	2, 3, f_writefile},
8474     {"xor",		2, 2, f_xor},
8475 };
8476 
8477 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
8478 
8479 /*
8480  * Function given to ExpandGeneric() to obtain the list of internal
8481  * or user defined function names.
8482  */
8483     char_u *
8484 get_function_name(expand_T *xp, int idx)
8485 {
8486     static int	intidx = -1;
8487     char_u	*name;
8488 
8489     if (idx == 0)
8490 	intidx = -1;
8491     if (intidx < 0)
8492     {
8493 	name = get_user_func_name(xp, idx);
8494 	if (name != NULL)
8495 	    return name;
8496     }
8497     if (++intidx < (int)(sizeof(functions) / sizeof(struct fst)))
8498     {
8499 	STRCPY(IObuff, functions[intidx].f_name);
8500 	STRCAT(IObuff, "(");
8501 	if (functions[intidx].f_max_argc == 0)
8502 	    STRCAT(IObuff, ")");
8503 	return IObuff;
8504     }
8505 
8506     return NULL;
8507 }
8508 
8509 /*
8510  * Function given to ExpandGeneric() to obtain the list of internal or
8511  * user defined variable or function names.
8512  */
8513     char_u *
8514 get_expr_name(expand_T *xp, int idx)
8515 {
8516     static int	intidx = -1;
8517     char_u	*name;
8518 
8519     if (idx == 0)
8520 	intidx = -1;
8521     if (intidx < 0)
8522     {
8523 	name = get_function_name(xp, idx);
8524 	if (name != NULL)
8525 	    return name;
8526     }
8527     return get_user_var_name(xp, ++intidx);
8528 }
8529 
8530 #endif /* FEAT_CMDL_COMPL */
8531 
8532 #if defined(EBCDIC) || defined(PROTO)
8533 /*
8534  * Compare struct fst by function name.
8535  */
8536     static int
8537 compare_func_name(const void *s1, const void *s2)
8538 {
8539     struct fst *p1 = (struct fst *)s1;
8540     struct fst *p2 = (struct fst *)s2;
8541 
8542     return STRCMP(p1->f_name, p2->f_name);
8543 }
8544 
8545 /*
8546  * Sort the function table by function name.
8547  * The sorting of the table above is ASCII dependant.
8548  * On machines using EBCDIC we have to sort it.
8549  */
8550     static void
8551 sortFunctions(void)
8552 {
8553     int		funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
8554 
8555     qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name);
8556 }
8557 #endif
8558 
8559 
8560 /*
8561  * Find internal function in table above.
8562  * Return index, or -1 if not found
8563  */
8564     static int
8565 find_internal_func(
8566     char_u	*name)		/* name of the function */
8567 {
8568     int		first = 0;
8569     int		last = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
8570     int		cmp;
8571     int		x;
8572 
8573     /*
8574      * Find the function name in the table. Binary search.
8575      */
8576     while (first <= last)
8577     {
8578 	x = first + ((unsigned)(last - first) >> 1);
8579 	cmp = STRCMP(name, functions[x].f_name);
8580 	if (cmp < 0)
8581 	    last = x - 1;
8582 	else if (cmp > 0)
8583 	    first = x + 1;
8584 	else
8585 	    return x;
8586     }
8587     return -1;
8588 }
8589 
8590 /*
8591  * Check if "name" is a variable of type VAR_FUNC.  If so, return the function
8592  * name it contains, otherwise return "name".
8593  * If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set
8594  * "partialp".
8595  */
8596     static char_u *
8597 deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload)
8598 {
8599     dictitem_T	*v;
8600     int		cc;
8601 
8602     if (partialp != NULL)
8603 	*partialp = NULL;
8604 
8605     cc = name[*lenp];
8606     name[*lenp] = NUL;
8607     v = find_var(name, NULL, no_autoload);
8608     name[*lenp] = cc;
8609     if (v != NULL && v->di_tv.v_type == VAR_FUNC)
8610     {
8611 	if (v->di_tv.vval.v_string == NULL)
8612 	{
8613 	    *lenp = 0;
8614 	    return (char_u *)"";	/* just in case */
8615 	}
8616 	*lenp = (int)STRLEN(v->di_tv.vval.v_string);
8617 	return v->di_tv.vval.v_string;
8618     }
8619 
8620     if (v != NULL && v->di_tv.v_type == VAR_PARTIAL)
8621     {
8622 	partial_T *pt = v->di_tv.vval.v_partial;
8623 
8624 	if (pt == NULL)
8625 	{
8626 	    *lenp = 0;
8627 	    return (char_u *)"";	/* just in case */
8628 	}
8629 	if (partialp != NULL)
8630 	    *partialp = pt;
8631 	*lenp = (int)STRLEN(pt->pt_name);
8632 	return pt->pt_name;
8633     }
8634 
8635     return name;
8636 }
8637 
8638 /*
8639  * Allocate a variable for the result of a function.
8640  * Return OK or FAIL.
8641  */
8642     static int
8643 get_func_tv(
8644     char_u	*name,		/* name of the function */
8645     int		len,		/* length of "name" */
8646     typval_T	*rettv,
8647     char_u	**arg,		/* argument, pointing to the '(' */
8648     linenr_T	firstline,	/* first line of range */
8649     linenr_T	lastline,	/* last line of range */
8650     int		*doesrange,	/* return: function handled range */
8651     int		evaluate,
8652     partial_T	*partial,	/* for extra arguments */
8653     dict_T	*selfdict)	/* Dictionary for "self" */
8654 {
8655     char_u	*argp;
8656     int		ret = OK;
8657     typval_T	argvars[MAX_FUNC_ARGS + 1];	/* vars for arguments */
8658     int		argcount = 0;		/* number of arguments found */
8659 
8660     /*
8661      * Get the arguments.
8662      */
8663     argp = *arg;
8664     while (argcount < MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc))
8665     {
8666 	argp = skipwhite(argp + 1);	    /* skip the '(' or ',' */
8667 	if (*argp == ')' || *argp == ',' || *argp == NUL)
8668 	    break;
8669 	if (eval1(&argp, &argvars[argcount], evaluate) == FAIL)
8670 	{
8671 	    ret = FAIL;
8672 	    break;
8673 	}
8674 	++argcount;
8675 	if (*argp != ',')
8676 	    break;
8677     }
8678     if (*argp == ')')
8679 	++argp;
8680     else
8681 	ret = FAIL;
8682 
8683     if (ret == OK)
8684 	ret = call_func(name, len, rettv, argcount, argvars,
8685 		 firstline, lastline, doesrange, evaluate, partial, selfdict);
8686     else if (!aborting())
8687     {
8688 	if (argcount == MAX_FUNC_ARGS)
8689 	    emsg_funcname(N_("E740: Too many arguments for function %s"), name);
8690 	else
8691 	    emsg_funcname(N_("E116: Invalid arguments for function %s"), name);
8692     }
8693 
8694     while (--argcount >= 0)
8695 	clear_tv(&argvars[argcount]);
8696 
8697     *arg = skipwhite(argp);
8698     return ret;
8699 }
8700 
8701 #define ERROR_UNKNOWN	0
8702 #define ERROR_TOOMANY	1
8703 #define ERROR_TOOFEW	2
8704 #define ERROR_SCRIPT	3
8705 #define ERROR_DICT	4
8706 #define ERROR_NONE	5
8707 #define ERROR_OTHER	6
8708 #define FLEN_FIXED 40
8709 
8710 /*
8711  * In a script change <SID>name() and s:name() to K_SNR 123_name().
8712  * Change <SNR>123_name() to K_SNR 123_name().
8713  * Use "fname_buf[FLEN_FIXED + 1]" when it fits, otherwise allocate memory
8714  * (slow).
8715  */
8716     static char_u *
8717 fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error)
8718 {
8719     int		llen;
8720     char_u	*fname;
8721     int		i;
8722 
8723     llen = eval_fname_script(name);
8724     if (llen > 0)
8725     {
8726 	fname_buf[0] = K_SPECIAL;
8727 	fname_buf[1] = KS_EXTRA;
8728 	fname_buf[2] = (int)KE_SNR;
8729 	i = 3;
8730 	if (eval_fname_sid(name))	/* "<SID>" or "s:" */
8731 	{
8732 	    if (current_SID <= 0)
8733 		*error = ERROR_SCRIPT;
8734 	    else
8735 	    {
8736 		sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID);
8737 		i = (int)STRLEN(fname_buf);
8738 	    }
8739 	}
8740 	if (i + STRLEN(name + llen) < FLEN_FIXED)
8741 	{
8742 	    STRCPY(fname_buf + i, name + llen);
8743 	    fname = fname_buf;
8744 	}
8745 	else
8746 	{
8747 	    fname = alloc((unsigned)(i + STRLEN(name + llen) + 1));
8748 	    if (fname == NULL)
8749 		*error = ERROR_OTHER;
8750 	    else
8751 	    {
8752 		*tofree = fname;
8753 		mch_memmove(fname, fname_buf, (size_t)i);
8754 		STRCPY(fname + i, name + llen);
8755 	    }
8756 	}
8757     }
8758     else
8759 	fname = name;
8760     return fname;
8761 }
8762 
8763 /*
8764  * Call a function with its resolved parameters
8765  * Return FAIL when the function can't be called,  OK otherwise.
8766  * Also returns OK when an error was encountered while executing the function.
8767  */
8768     int
8769 call_func(
8770     char_u	*funcname,	/* name of the function */
8771     int		len,		/* length of "name" */
8772     typval_T	*rettv,		/* return value goes here */
8773     int		argcount_in,	/* number of "argvars" */
8774     typval_T	*argvars_in,	/* vars for arguments, must have "argcount"
8775 				   PLUS ONE elements! */
8776     linenr_T	firstline,	/* first line of range */
8777     linenr_T	lastline,	/* last line of range */
8778     int		*doesrange,	/* return: function handled range */
8779     int		evaluate,
8780     partial_T	*partial,	/* optional, can be NULL */
8781     dict_T	*selfdict_in)	/* Dictionary for "self" */
8782 {
8783     int		ret = FAIL;
8784     int		error = ERROR_NONE;
8785     int		i;
8786     ufunc_T	*fp;
8787     char_u	fname_buf[FLEN_FIXED + 1];
8788     char_u	*tofree = NULL;
8789     char_u	*fname;
8790     char_u	*name;
8791     int		argcount = argcount_in;
8792     typval_T	*argvars = argvars_in;
8793     dict_T	*selfdict = selfdict_in;
8794     typval_T	argv[MAX_FUNC_ARGS + 1]; /* used when "partial" is not NULL */
8795     int		argv_clear = 0;
8796 
8797     /* Make a copy of the name, if it comes from a funcref variable it could
8798      * be changed or deleted in the called function. */
8799     name = vim_strnsave(funcname, len);
8800     if (name == NULL)
8801 	return ret;
8802 
8803     fname = fname_trans_sid(name, fname_buf, &tofree, &error);
8804 
8805     *doesrange = FALSE;
8806 
8807     if (partial != NULL)
8808     {
8809 	if (partial->pt_dict != NULL)
8810 	{
8811 	    /* When the function has a partial with a dict and there is a dict
8812 	     * argument, use the dict argument.  That is backwards compatible.
8813 	     */
8814 	    if (selfdict_in == NULL)
8815 		selfdict = partial->pt_dict;
8816 	}
8817 	if (error == ERROR_NONE && partial->pt_argc > 0)
8818 	{
8819 	    for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear)
8820 		copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]);
8821 	    for (i = 0; i < argcount_in; ++i)
8822 		argv[i + argv_clear] = argvars_in[i];
8823 	    argvars = argv;
8824 	    argcount = partial->pt_argc + argcount_in;
8825 	}
8826     }
8827 
8828 
8829     /* execute the function if no errors detected and executing */
8830     if (evaluate && error == ERROR_NONE)
8831     {
8832 	char_u *rfname = fname;
8833 
8834 	/* Ignore "g:" before a function name. */
8835 	if (fname[0] == 'g' && fname[1] == ':')
8836 	    rfname = fname + 2;
8837 
8838 	rettv->v_type = VAR_NUMBER;	/* default rettv is number zero */
8839 	rettv->vval.v_number = 0;
8840 	error = ERROR_UNKNOWN;
8841 
8842 	if (!builtin_function(rfname, -1))
8843 	{
8844 	    /*
8845 	     * User defined function.
8846 	     */
8847 	    fp = find_func(rfname);
8848 
8849 #ifdef FEAT_AUTOCMD
8850 	    /* Trigger FuncUndefined event, may load the function. */
8851 	    if (fp == NULL
8852 		    && apply_autocmds(EVENT_FUNCUNDEFINED,
8853 						     rfname, rfname, TRUE, NULL)
8854 		    && !aborting())
8855 	    {
8856 		/* executed an autocommand, search for the function again */
8857 		fp = find_func(rfname);
8858 	    }
8859 #endif
8860 	    /* Try loading a package. */
8861 	    if (fp == NULL && script_autoload(rfname, TRUE) && !aborting())
8862 	    {
8863 		/* loaded a package, search for the function again */
8864 		fp = find_func(rfname);
8865 	    }
8866 
8867 	    if (fp != NULL)
8868 	    {
8869 		if (fp->uf_flags & FC_RANGE)
8870 		    *doesrange = TRUE;
8871 		if (argcount < fp->uf_args.ga_len)
8872 		    error = ERROR_TOOFEW;
8873 		else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len)
8874 		    error = ERROR_TOOMANY;
8875 		else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
8876 		    error = ERROR_DICT;
8877 		else
8878 		{
8879 		    int did_save_redo = FALSE;
8880 
8881 		    /*
8882 		     * Call the user function.
8883 		     * Save and restore search patterns, script variables and
8884 		     * redo buffer.
8885 		     */
8886 		    save_search_patterns();
8887 #ifdef FEAT_INS_EXPAND
8888 		    if (!ins_compl_active())
8889 #endif
8890 		    {
8891 			saveRedobuff();
8892 			did_save_redo = TRUE;
8893 		    }
8894 		    ++fp->uf_calls;
8895 		    call_user_func(fp, argcount, argvars, rettv,
8896 					       firstline, lastline,
8897 				  (fp->uf_flags & FC_DICT) ? selfdict : NULL);
8898 		    if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name)
8899 						      && fp->uf_refcount <= 0)
8900 			/* Function was unreferenced while being used, free it
8901 			 * now. */
8902 			func_free(fp);
8903 		    if (did_save_redo)
8904 			restoreRedobuff();
8905 		    restore_search_patterns();
8906 		    error = ERROR_NONE;
8907 		}
8908 	    }
8909 	}
8910 	else
8911 	{
8912 	    /*
8913 	     * Find the function name in the table, call its implementation.
8914 	     */
8915 	    i = find_internal_func(fname);
8916 	    if (i >= 0)
8917 	    {
8918 		if (argcount < functions[i].f_min_argc)
8919 		    error = ERROR_TOOFEW;
8920 		else if (argcount > functions[i].f_max_argc)
8921 		    error = ERROR_TOOMANY;
8922 		else
8923 		{
8924 		    argvars[argcount].v_type = VAR_UNKNOWN;
8925 		    functions[i].f_func(argvars, rettv);
8926 		    error = ERROR_NONE;
8927 		}
8928 	    }
8929 	}
8930 	/*
8931 	 * The function call (or "FuncUndefined" autocommand sequence) might
8932 	 * have been aborted by an error, an interrupt, or an explicitly thrown
8933 	 * exception that has not been caught so far.  This situation can be
8934 	 * tested for by calling aborting().  For an error in an internal
8935 	 * function or for the "E132" error in call_user_func(), however, the
8936 	 * throw point at which the "force_abort" flag (temporarily reset by
8937 	 * emsg()) is normally updated has not been reached yet. We need to
8938 	 * update that flag first to make aborting() reliable.
8939 	 */
8940 	update_force_abort();
8941     }
8942     if (error == ERROR_NONE)
8943 	ret = OK;
8944 
8945     /*
8946      * Report an error unless the argument evaluation or function call has been
8947      * cancelled due to an aborting error, an interrupt, or an exception.
8948      */
8949     if (!aborting())
8950     {
8951 	switch (error)
8952 	{
8953 	    case ERROR_UNKNOWN:
8954 		    emsg_funcname(N_("E117: Unknown function: %s"), name);
8955 		    break;
8956 	    case ERROR_TOOMANY:
8957 		    emsg_funcname(e_toomanyarg, name);
8958 		    break;
8959 	    case ERROR_TOOFEW:
8960 		    emsg_funcname(N_("E119: Not enough arguments for function: %s"),
8961 									name);
8962 		    break;
8963 	    case ERROR_SCRIPT:
8964 		    emsg_funcname(N_("E120: Using <SID> not in a script context: %s"),
8965 									name);
8966 		    break;
8967 	    case ERROR_DICT:
8968 		    emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
8969 									name);
8970 		    break;
8971 	}
8972     }
8973 
8974     while (argv_clear > 0)
8975 	clear_tv(&argv[--argv_clear]);
8976     vim_free(tofree);
8977     vim_free(name);
8978 
8979     return ret;
8980 }
8981 
8982 /*
8983  * Give an error message with a function name.  Handle <SNR> things.
8984  * "ermsg" is to be passed without translation, use N_() instead of _().
8985  */
8986     static void
8987 emsg_funcname(char *ermsg, char_u *name)
8988 {
8989     char_u	*p;
8990 
8991     if (*name == K_SPECIAL)
8992 	p = concat_str((char_u *)"<SNR>", name + 3);
8993     else
8994 	p = name;
8995     EMSG2(_(ermsg), p);
8996     if (p != name)
8997 	vim_free(p);
8998 }
8999 
9000 /*
9001  * Return TRUE for a non-zero Number and a non-empty String.
9002  */
9003     static int
9004 non_zero_arg(typval_T *argvars)
9005 {
9006     return ((argvars[0].v_type == VAR_NUMBER
9007 		&& argvars[0].vval.v_number != 0)
9008 	    || (argvars[0].v_type == VAR_STRING
9009 		&& argvars[0].vval.v_string != NULL
9010 		&& *argvars[0].vval.v_string != NUL));
9011 }
9012 
9013 /*********************************************
9014  * Implementation of the built-in functions
9015  */
9016 
9017 #ifdef FEAT_FLOAT
9018 static int get_float_arg(typval_T *argvars, float_T *f);
9019 
9020 /*
9021  * Get the float value of "argvars[0]" into "f".
9022  * Returns FAIL when the argument is not a Number or Float.
9023  */
9024     static int
9025 get_float_arg(typval_T *argvars, float_T *f)
9026 {
9027     if (argvars[0].v_type == VAR_FLOAT)
9028     {
9029 	*f = argvars[0].vval.v_float;
9030 	return OK;
9031     }
9032     if (argvars[0].v_type == VAR_NUMBER)
9033     {
9034 	*f = (float_T)argvars[0].vval.v_number;
9035 	return OK;
9036     }
9037     EMSG(_("E808: Number or Float required"));
9038     return FAIL;
9039 }
9040 
9041 /*
9042  * "abs(expr)" function
9043  */
9044     static void
9045 f_abs(typval_T *argvars, typval_T *rettv)
9046 {
9047     if (argvars[0].v_type == VAR_FLOAT)
9048     {
9049 	rettv->v_type = VAR_FLOAT;
9050 	rettv->vval.v_float = fabs(argvars[0].vval.v_float);
9051     }
9052     else
9053     {
9054 	varnumber_T	n;
9055 	int		error = FALSE;
9056 
9057 	n = get_tv_number_chk(&argvars[0], &error);
9058 	if (error)
9059 	    rettv->vval.v_number = -1;
9060 	else if (n > 0)
9061 	    rettv->vval.v_number = n;
9062 	else
9063 	    rettv->vval.v_number = -n;
9064     }
9065 }
9066 
9067 /*
9068  * "acos()" function
9069  */
9070     static void
9071 f_acos(typval_T *argvars, typval_T *rettv)
9072 {
9073     float_T	f = 0.0;
9074 
9075     rettv->v_type = VAR_FLOAT;
9076     if (get_float_arg(argvars, &f) == OK)
9077 	rettv->vval.v_float = acos(f);
9078     else
9079 	rettv->vval.v_float = 0.0;
9080 }
9081 #endif
9082 
9083 /*
9084  * "add(list, item)" function
9085  */
9086     static void
9087 f_add(typval_T *argvars, typval_T *rettv)
9088 {
9089     list_T	*l;
9090 
9091     rettv->vval.v_number = 1; /* Default: Failed */
9092     if (argvars[0].v_type == VAR_LIST)
9093     {
9094 	if ((l = argvars[0].vval.v_list) != NULL
9095 		&& !tv_check_lock(l->lv_lock,
9096 					 (char_u *)N_("add() argument"), TRUE)
9097 		&& list_append_tv(l, &argvars[1]) == OK)
9098 	    copy_tv(&argvars[0], rettv);
9099     }
9100     else
9101 	EMSG(_(e_listreq));
9102 }
9103 
9104 /*
9105  * "alloc_fail(id, countdown, repeat)" function
9106  */
9107     static void
9108 f_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
9109 {
9110     if (argvars[0].v_type != VAR_NUMBER
9111 	    || argvars[0].vval.v_number <= 0
9112 	    || argvars[1].v_type != VAR_NUMBER
9113 	    || argvars[1].vval.v_number < 0
9114 	    || argvars[2].v_type != VAR_NUMBER)
9115 	EMSG(_(e_invarg));
9116     else
9117     {
9118 	alloc_fail_id = argvars[0].vval.v_number;
9119 	if (alloc_fail_id >= aid_last)
9120 	    EMSG(_(e_invarg));
9121 	alloc_fail_countdown = argvars[1].vval.v_number;
9122 	alloc_fail_repeat = argvars[2].vval.v_number;
9123 	did_outofmem_msg = FALSE;
9124     }
9125 }
9126 
9127 /*
9128  * "and(expr, expr)" function
9129  */
9130     static void
9131 f_and(typval_T *argvars, typval_T *rettv)
9132 {
9133     rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
9134 					& get_tv_number_chk(&argvars[1], NULL);
9135 }
9136 
9137 /*
9138  * "append(lnum, string/list)" function
9139  */
9140     static void
9141 f_append(typval_T *argvars, typval_T *rettv)
9142 {
9143     long	lnum;
9144     char_u	*line;
9145     list_T	*l = NULL;
9146     listitem_T	*li = NULL;
9147     typval_T	*tv;
9148     long	added = 0;
9149 
9150     /* When coming here from Insert mode, sync undo, so that this can be
9151      * undone separately from what was previously inserted. */
9152     if (u_sync_once == 2)
9153     {
9154 	u_sync_once = 1; /* notify that u_sync() was called */
9155 	u_sync(TRUE);
9156     }
9157 
9158     lnum = get_tv_lnum(argvars);
9159     if (lnum >= 0
9160 	    && lnum <= curbuf->b_ml.ml_line_count
9161 	    && u_save(lnum, lnum + 1) == OK)
9162     {
9163 	if (argvars[1].v_type == VAR_LIST)
9164 	{
9165 	    l = argvars[1].vval.v_list;
9166 	    if (l == NULL)
9167 		return;
9168 	    li = l->lv_first;
9169 	}
9170 	for (;;)
9171 	{
9172 	    if (l == NULL)
9173 		tv = &argvars[1];	/* append a string */
9174 	    else if (li == NULL)
9175 		break;			/* end of list */
9176 	    else
9177 		tv = &li->li_tv;	/* append item from list */
9178 	    line = get_tv_string_chk(tv);
9179 	    if (line == NULL)		/* type error */
9180 	    {
9181 		rettv->vval.v_number = 1;	/* Failed */
9182 		break;
9183 	    }
9184 	    ml_append(lnum + added, line, (colnr_T)0, FALSE);
9185 	    ++added;
9186 	    if (l == NULL)
9187 		break;
9188 	    li = li->li_next;
9189 	}
9190 
9191 	appended_lines_mark(lnum, added);
9192 	if (curwin->w_cursor.lnum > lnum)
9193 	    curwin->w_cursor.lnum += added;
9194     }
9195     else
9196 	rettv->vval.v_number = 1;	/* Failed */
9197 }
9198 
9199 /*
9200  * "argc()" function
9201  */
9202     static void
9203 f_argc(typval_T *argvars UNUSED, typval_T *rettv)
9204 {
9205     rettv->vval.v_number = ARGCOUNT;
9206 }
9207 
9208 /*
9209  * "argidx()" function
9210  */
9211     static void
9212 f_argidx(typval_T *argvars UNUSED, typval_T *rettv)
9213 {
9214     rettv->vval.v_number = curwin->w_arg_idx;
9215 }
9216 
9217 /*
9218  * "arglistid()" function
9219  */
9220     static void
9221 f_arglistid(typval_T *argvars, typval_T *rettv)
9222 {
9223     win_T	*wp;
9224 
9225     rettv->vval.v_number = -1;
9226     wp = find_tabwin(&argvars[0], &argvars[1]);
9227     if (wp != NULL)
9228 	rettv->vval.v_number = wp->w_alist->id;
9229 }
9230 
9231 /*
9232  * "argv(nr)" function
9233  */
9234     static void
9235 f_argv(typval_T *argvars, typval_T *rettv)
9236 {
9237     int		idx;
9238 
9239     if (argvars[0].v_type != VAR_UNKNOWN)
9240     {
9241 	idx = get_tv_number_chk(&argvars[0], NULL);
9242 	if (idx >= 0 && idx < ARGCOUNT)
9243 	    rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
9244 	else
9245 	    rettv->vval.v_string = NULL;
9246 	rettv->v_type = VAR_STRING;
9247     }
9248     else if (rettv_list_alloc(rettv) == OK)
9249 	for (idx = 0; idx < ARGCOUNT; ++idx)
9250 	    list_append_string(rettv->vval.v_list,
9251 					       alist_name(&ARGLIST[idx]), -1);
9252 }
9253 
9254 static void prepare_assert_error(garray_T*gap);
9255 static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, typval_T *got_tv);
9256 static void assert_error(garray_T *gap);
9257 static void assert_bool(typval_T *argvars, int isTrue);
9258 
9259 /*
9260  * Prepare "gap" for an assert error and add the sourcing position.
9261  */
9262     static void
9263 prepare_assert_error(garray_T *gap)
9264 {
9265     char buf[NUMBUFLEN];
9266 
9267     ga_init2(gap, 1, 100);
9268     if (sourcing_name != NULL)
9269     {
9270 	ga_concat(gap, sourcing_name);
9271 	if (sourcing_lnum > 0)
9272 	    ga_concat(gap, (char_u *)" ");
9273     }
9274     if (sourcing_lnum > 0)
9275     {
9276 	sprintf(buf, "line %ld", (long)sourcing_lnum);
9277 	ga_concat(gap, (char_u *)buf);
9278     }
9279     if (sourcing_name != NULL || sourcing_lnum > 0)
9280 	ga_concat(gap, (char_u *)": ");
9281 }
9282 
9283 /*
9284  * Append "str" to "gap", escaping unprintable characters.
9285  * Changes NL to \n, CR to \r, etc.
9286  */
9287     static void
9288 ga_concat_esc(garray_T *gap, char_u *str)
9289 {
9290     char_u  *p;
9291     char_u  buf[NUMBUFLEN];
9292 
9293     if (str == NULL)
9294     {
9295 	ga_concat(gap, (char_u *)"NULL");
9296 	return;
9297     }
9298 
9299     for (p = str; *p != NUL; ++p)
9300 	switch (*p)
9301 	{
9302 	    case BS: ga_concat(gap, (char_u *)"\\b"); break;
9303 	    case ESC: ga_concat(gap, (char_u *)"\\e"); break;
9304 	    case FF: ga_concat(gap, (char_u *)"\\f"); break;
9305 	    case NL: ga_concat(gap, (char_u *)"\\n"); break;
9306 	    case TAB: ga_concat(gap, (char_u *)"\\t"); break;
9307 	    case CAR: ga_concat(gap, (char_u *)"\\r"); break;
9308 	    case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
9309 	    default:
9310 		if (*p < ' ')
9311 		{
9312 		    vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
9313 		    ga_concat(gap, buf);
9314 		}
9315 		else
9316 		    ga_append(gap, *p);
9317 		break;
9318 	}
9319 }
9320 
9321 /*
9322  * Fill "gap" with information about an assert error.
9323  */
9324     static void
9325 fill_assert_error(
9326     garray_T	*gap,
9327     typval_T	*opt_msg_tv,
9328     char_u      *exp_str,
9329     typval_T	*exp_tv,
9330     typval_T	*got_tv)
9331 {
9332     char_u	numbuf[NUMBUFLEN];
9333     char_u	*tofree;
9334 
9335     if (opt_msg_tv->v_type != VAR_UNKNOWN)
9336     {
9337 	ga_concat(gap, tv2string(opt_msg_tv, &tofree, numbuf, 0));
9338 	vim_free(tofree);
9339     }
9340     else
9341     {
9342 	ga_concat(gap, (char_u *)"Expected ");
9343 	if (exp_str == NULL)
9344 	{
9345 	    ga_concat_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
9346 	    vim_free(tofree);
9347 	}
9348 	else
9349 	    ga_concat_esc(gap, exp_str);
9350 	ga_concat(gap, (char_u *)" but got ");
9351 	ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
9352 	vim_free(tofree);
9353     }
9354 }
9355 
9356 /*
9357  * Add an assert error to v:errors.
9358  */
9359     static void
9360 assert_error(garray_T *gap)
9361 {
9362     struct vimvar   *vp = &vimvars[VV_ERRORS];
9363 
9364     if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL)
9365 	/* Make sure v:errors is a list. */
9366 	set_vim_var_list(VV_ERRORS, list_alloc());
9367     list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
9368 }
9369 
9370 /*
9371  * "assert_equal(expected, actual[, msg])" function
9372  */
9373     static void
9374 f_assert_equal(typval_T *argvars, typval_T *rettv UNUSED)
9375 {
9376     garray_T	ga;
9377 
9378     if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE))
9379     {
9380 	prepare_assert_error(&ga);
9381 	fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1]);
9382 	assert_error(&ga);
9383 	ga_clear(&ga);
9384     }
9385 }
9386 
9387 /*
9388  * "assert_exception(string[, msg])" function
9389  */
9390     static void
9391 f_assert_exception(typval_T *argvars, typval_T *rettv UNUSED)
9392 {
9393     garray_T	ga;
9394     char	*error;
9395 
9396     error = (char *)get_tv_string_chk(&argvars[0]);
9397     if (vimvars[VV_EXCEPTION].vv_str == NULL)
9398     {
9399 	prepare_assert_error(&ga);
9400 	ga_concat(&ga, (char_u *)"v:exception is not set");
9401 	assert_error(&ga);
9402 	ga_clear(&ga);
9403     }
9404     else if (error != NULL
9405 	    && strstr((char *)vimvars[VV_EXCEPTION].vv_str, error) == NULL)
9406     {
9407 	prepare_assert_error(&ga);
9408 	fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
9409 						&vimvars[VV_EXCEPTION].vv_tv);
9410 	assert_error(&ga);
9411 	ga_clear(&ga);
9412     }
9413 }
9414 
9415 /*
9416  * "assert_fails(cmd [, error])" function
9417  */
9418     static void
9419 f_assert_fails(typval_T *argvars, typval_T *rettv UNUSED)
9420 {
9421     char_u	*cmd = get_tv_string_chk(&argvars[0]);
9422     garray_T	ga;
9423 
9424     called_emsg = FALSE;
9425     suppress_errthrow = TRUE;
9426     emsg_silent = TRUE;
9427     do_cmdline_cmd(cmd);
9428     if (!called_emsg)
9429     {
9430 	prepare_assert_error(&ga);
9431 	ga_concat(&ga, (char_u *)"command did not fail: ");
9432 	ga_concat(&ga, cmd);
9433 	assert_error(&ga);
9434 	ga_clear(&ga);
9435     }
9436     else if (argvars[1].v_type != VAR_UNKNOWN)
9437     {
9438 	char_u	buf[NUMBUFLEN];
9439 	char	*error = (char *)get_tv_string_buf_chk(&argvars[1], buf);
9440 
9441 	if (error == NULL
9442 		  || strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL)
9443 	{
9444 	    prepare_assert_error(&ga);
9445 	    fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
9446 						&vimvars[VV_ERRMSG].vv_tv);
9447 	    assert_error(&ga);
9448 	    ga_clear(&ga);
9449 	}
9450     }
9451 
9452     called_emsg = FALSE;
9453     suppress_errthrow = FALSE;
9454     emsg_silent = FALSE;
9455     emsg_on_display = FALSE;
9456     set_vim_var_string(VV_ERRMSG, NULL, 0);
9457 }
9458 
9459 /*
9460  * Common for assert_true() and assert_false().
9461  */
9462     static void
9463 assert_bool(typval_T *argvars, int isTrue)
9464 {
9465     int		error = FALSE;
9466     garray_T	ga;
9467 
9468     if (argvars[0].v_type == VAR_SPECIAL
9469 	    && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE))
9470 	return;
9471     if (argvars[0].v_type != VAR_NUMBER
9472 	    || (get_tv_number_chk(&argvars[0], &error) == 0) == isTrue
9473 	    || error)
9474     {
9475 	prepare_assert_error(&ga);
9476 	fill_assert_error(&ga, &argvars[1],
9477 		(char_u *)(isTrue ? "True" : "False"),
9478 		NULL, &argvars[0]);
9479 	assert_error(&ga);
9480 	ga_clear(&ga);
9481     }
9482 }
9483 
9484 /*
9485  * "assert_false(actual[, msg])" function
9486  */
9487     static void
9488 f_assert_false(typval_T *argvars, typval_T *rettv UNUSED)
9489 {
9490     assert_bool(argvars, FALSE);
9491 }
9492 
9493 /*
9494  * "assert_true(actual[, msg])" function
9495  */
9496     static void
9497 f_assert_true(typval_T *argvars, typval_T *rettv UNUSED)
9498 {
9499     assert_bool(argvars, TRUE);
9500 }
9501 
9502 #ifdef FEAT_FLOAT
9503 /*
9504  * "asin()" function
9505  */
9506     static void
9507 f_asin(typval_T *argvars, typval_T *rettv)
9508 {
9509     float_T	f = 0.0;
9510 
9511     rettv->v_type = VAR_FLOAT;
9512     if (get_float_arg(argvars, &f) == OK)
9513 	rettv->vval.v_float = asin(f);
9514     else
9515 	rettv->vval.v_float = 0.0;
9516 }
9517 
9518 /*
9519  * "atan()" function
9520  */
9521     static void
9522 f_atan(typval_T *argvars, typval_T *rettv)
9523 {
9524     float_T	f = 0.0;
9525 
9526     rettv->v_type = VAR_FLOAT;
9527     if (get_float_arg(argvars, &f) == OK)
9528 	rettv->vval.v_float = atan(f);
9529     else
9530 	rettv->vval.v_float = 0.0;
9531 }
9532 
9533 /*
9534  * "atan2()" function
9535  */
9536     static void
9537 f_atan2(typval_T *argvars, typval_T *rettv)
9538 {
9539     float_T	fx = 0.0, fy = 0.0;
9540 
9541     rettv->v_type = VAR_FLOAT;
9542     if (get_float_arg(argvars, &fx) == OK
9543 				     && get_float_arg(&argvars[1], &fy) == OK)
9544 	rettv->vval.v_float = atan2(fx, fy);
9545     else
9546 	rettv->vval.v_float = 0.0;
9547 }
9548 #endif
9549 
9550 /*
9551  * "browse(save, title, initdir, default)" function
9552  */
9553     static void
9554 f_browse(typval_T *argvars UNUSED, typval_T *rettv)
9555 {
9556 #ifdef FEAT_BROWSE
9557     int		save;
9558     char_u	*title;
9559     char_u	*initdir;
9560     char_u	*defname;
9561     char_u	buf[NUMBUFLEN];
9562     char_u	buf2[NUMBUFLEN];
9563     int		error = FALSE;
9564 
9565     save = get_tv_number_chk(&argvars[0], &error);
9566     title = get_tv_string_chk(&argvars[1]);
9567     initdir = get_tv_string_buf_chk(&argvars[2], buf);
9568     defname = get_tv_string_buf_chk(&argvars[3], buf2);
9569 
9570     if (error || title == NULL || initdir == NULL || defname == NULL)
9571 	rettv->vval.v_string = NULL;
9572     else
9573 	rettv->vval.v_string =
9574 		 do_browse(save ? BROWSE_SAVE : 0,
9575 				 title, defname, NULL, initdir, NULL, curbuf);
9576 #else
9577     rettv->vval.v_string = NULL;
9578 #endif
9579     rettv->v_type = VAR_STRING;
9580 }
9581 
9582 /*
9583  * "browsedir(title, initdir)" function
9584  */
9585     static void
9586 f_browsedir(typval_T *argvars UNUSED, typval_T *rettv)
9587 {
9588 #ifdef FEAT_BROWSE
9589     char_u	*title;
9590     char_u	*initdir;
9591     char_u	buf[NUMBUFLEN];
9592 
9593     title = get_tv_string_chk(&argvars[0]);
9594     initdir = get_tv_string_buf_chk(&argvars[1], buf);
9595 
9596     if (title == NULL || initdir == NULL)
9597 	rettv->vval.v_string = NULL;
9598     else
9599 	rettv->vval.v_string = do_browse(BROWSE_DIR,
9600 				    title, NULL, NULL, initdir, NULL, curbuf);
9601 #else
9602     rettv->vval.v_string = NULL;
9603 #endif
9604     rettv->v_type = VAR_STRING;
9605 }
9606 
9607 static buf_T *find_buffer(typval_T *avar);
9608 
9609 /*
9610  * Find a buffer by number or exact name.
9611  */
9612     static buf_T *
9613 find_buffer(typval_T *avar)
9614 {
9615     buf_T	*buf = NULL;
9616 
9617     if (avar->v_type == VAR_NUMBER)
9618 	buf = buflist_findnr((int)avar->vval.v_number);
9619     else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL)
9620     {
9621 	buf = buflist_findname_exp(avar->vval.v_string);
9622 	if (buf == NULL)
9623 	{
9624 	    /* No full path name match, try a match with a URL or a "nofile"
9625 	     * buffer, these don't use the full path. */
9626 	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
9627 		if (buf->b_fname != NULL
9628 			&& (path_with_url(buf->b_fname)
9629 #ifdef FEAT_QUICKFIX
9630 			    || bt_nofile(buf)
9631 #endif
9632 			   )
9633 			&& STRCMP(buf->b_fname, avar->vval.v_string) == 0)
9634 		    break;
9635 	}
9636     }
9637     return buf;
9638 }
9639 
9640 /*
9641  * "bufexists(expr)" function
9642  */
9643     static void
9644 f_bufexists(typval_T *argvars, typval_T *rettv)
9645 {
9646     rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL);
9647 }
9648 
9649 /*
9650  * "buflisted(expr)" function
9651  */
9652     static void
9653 f_buflisted(typval_T *argvars, typval_T *rettv)
9654 {
9655     buf_T	*buf;
9656 
9657     buf = find_buffer(&argvars[0]);
9658     rettv->vval.v_number = (buf != NULL && buf->b_p_bl);
9659 }
9660 
9661 /*
9662  * "bufloaded(expr)" function
9663  */
9664     static void
9665 f_bufloaded(typval_T *argvars, typval_T *rettv)
9666 {
9667     buf_T	*buf;
9668 
9669     buf = find_buffer(&argvars[0]);
9670     rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
9671 }
9672 
9673     buf_T *
9674 buflist_find_by_name(char_u *name, int curtab_only)
9675 {
9676     int		save_magic;
9677     char_u	*save_cpo;
9678     buf_T	*buf;
9679 
9680     /* Ignore 'magic' and 'cpoptions' here to make scripts portable */
9681     save_magic = p_magic;
9682     p_magic = TRUE;
9683     save_cpo = p_cpo;
9684     p_cpo = (char_u *)"";
9685 
9686     buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
9687 						    TRUE, FALSE, curtab_only));
9688 
9689     p_magic = save_magic;
9690     p_cpo = save_cpo;
9691     return buf;
9692 }
9693 
9694 /*
9695  * Get buffer by number or pattern.
9696  */
9697     static buf_T *
9698 get_buf_tv(typval_T *tv, int curtab_only)
9699 {
9700     char_u	*name = tv->vval.v_string;
9701     buf_T	*buf;
9702 
9703     if (tv->v_type == VAR_NUMBER)
9704 	return buflist_findnr((int)tv->vval.v_number);
9705     if (tv->v_type != VAR_STRING)
9706 	return NULL;
9707     if (name == NULL || *name == NUL)
9708 	return curbuf;
9709     if (name[0] == '$' && name[1] == NUL)
9710 	return lastbuf;
9711 
9712     buf = buflist_find_by_name(name, curtab_only);
9713 
9714     /* If not found, try expanding the name, like done for bufexists(). */
9715     if (buf == NULL)
9716 	buf = find_buffer(tv);
9717 
9718     return buf;
9719 }
9720 
9721 /*
9722  * "bufname(expr)" function
9723  */
9724     static void
9725 f_bufname(typval_T *argvars, typval_T *rettv)
9726 {
9727     buf_T	*buf;
9728 
9729     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
9730     ++emsg_off;
9731     buf = get_buf_tv(&argvars[0], FALSE);
9732     rettv->v_type = VAR_STRING;
9733     if (buf != NULL && buf->b_fname != NULL)
9734 	rettv->vval.v_string = vim_strsave(buf->b_fname);
9735     else
9736 	rettv->vval.v_string = NULL;
9737     --emsg_off;
9738 }
9739 
9740 /*
9741  * "bufnr(expr)" function
9742  */
9743     static void
9744 f_bufnr(typval_T *argvars, typval_T *rettv)
9745 {
9746     buf_T	*buf;
9747     int		error = FALSE;
9748     char_u	*name;
9749 
9750     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
9751     ++emsg_off;
9752     buf = get_buf_tv(&argvars[0], FALSE);
9753     --emsg_off;
9754 
9755     /* If the buffer isn't found and the second argument is not zero create a
9756      * new buffer. */
9757     if (buf == NULL
9758 	    && argvars[1].v_type != VAR_UNKNOWN
9759 	    && get_tv_number_chk(&argvars[1], &error) != 0
9760 	    && !error
9761 	    && (name = get_tv_string_chk(&argvars[0])) != NULL
9762 	    && !error)
9763 	buf = buflist_new(name, NULL, (linenr_T)1, 0);
9764 
9765     if (buf != NULL)
9766 	rettv->vval.v_number = buf->b_fnum;
9767     else
9768 	rettv->vval.v_number = -1;
9769 }
9770 
9771 /*
9772  * "bufwinnr(nr)" function
9773  */
9774     static void
9775 f_bufwinnr(typval_T *argvars, typval_T *rettv)
9776 {
9777 #ifdef FEAT_WINDOWS
9778     win_T	*wp;
9779     int		winnr = 0;
9780 #endif
9781     buf_T	*buf;
9782 
9783     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
9784     ++emsg_off;
9785     buf = get_buf_tv(&argvars[0], TRUE);
9786 #ifdef FEAT_WINDOWS
9787     for (wp = firstwin; wp; wp = wp->w_next)
9788     {
9789 	++winnr;
9790 	if (wp->w_buffer == buf)
9791 	    break;
9792     }
9793     rettv->vval.v_number = (wp != NULL ? winnr : -1);
9794 #else
9795     rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1);
9796 #endif
9797     --emsg_off;
9798 }
9799 
9800 /*
9801  * "byte2line(byte)" function
9802  */
9803     static void
9804 f_byte2line(typval_T *argvars UNUSED, typval_T *rettv)
9805 {
9806 #ifndef FEAT_BYTEOFF
9807     rettv->vval.v_number = -1;
9808 #else
9809     long	boff = 0;
9810 
9811     boff = get_tv_number(&argvars[0]) - 1;  /* boff gets -1 on type error */
9812     if (boff < 0)
9813 	rettv->vval.v_number = -1;
9814     else
9815 	rettv->vval.v_number = ml_find_line_or_offset(curbuf,
9816 							  (linenr_T)0, &boff);
9817 #endif
9818 }
9819 
9820     static void
9821 byteidx(typval_T *argvars, typval_T *rettv, int comp UNUSED)
9822 {
9823 #ifdef FEAT_MBYTE
9824     char_u	*t;
9825 #endif
9826     char_u	*str;
9827     long	idx;
9828 
9829     str = get_tv_string_chk(&argvars[0]);
9830     idx = get_tv_number_chk(&argvars[1], NULL);
9831     rettv->vval.v_number = -1;
9832     if (str == NULL || idx < 0)
9833 	return;
9834 
9835 #ifdef FEAT_MBYTE
9836     t = str;
9837     for ( ; idx > 0; idx--)
9838     {
9839 	if (*t == NUL)		/* EOL reached */
9840 	    return;
9841 	if (enc_utf8 && comp)
9842 	    t += utf_ptr2len(t);
9843 	else
9844 	    t += (*mb_ptr2len)(t);
9845     }
9846     rettv->vval.v_number = (varnumber_T)(t - str);
9847 #else
9848     if ((size_t)idx <= STRLEN(str))
9849 	rettv->vval.v_number = idx;
9850 #endif
9851 }
9852 
9853 /*
9854  * "byteidx()" function
9855  */
9856     static void
9857 f_byteidx(typval_T *argvars, typval_T *rettv)
9858 {
9859     byteidx(argvars, rettv, FALSE);
9860 }
9861 
9862 /*
9863  * "byteidxcomp()" function
9864  */
9865     static void
9866 f_byteidxcomp(typval_T *argvars, typval_T *rettv)
9867 {
9868     byteidx(argvars, rettv, TRUE);
9869 }
9870 
9871     int
9872 func_call(
9873     char_u	*name,
9874     typval_T	*args,
9875     partial_T	*partial,
9876     dict_T	*selfdict,
9877     typval_T	*rettv)
9878 {
9879     listitem_T	*item;
9880     typval_T	argv[MAX_FUNC_ARGS + 1];
9881     int		argc = 0;
9882     int		dummy;
9883     int		r = 0;
9884 
9885     for (item = args->vval.v_list->lv_first; item != NULL;
9886 							 item = item->li_next)
9887     {
9888 	if (argc == MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc))
9889 	{
9890 	    EMSG(_("E699: Too many arguments"));
9891 	    break;
9892 	}
9893 	/* Make a copy of each argument.  This is needed to be able to set
9894 	 * v_lock to VAR_FIXED in the copy without changing the original list.
9895 	 */
9896 	copy_tv(&item->li_tv, &argv[argc++]);
9897     }
9898 
9899     if (item == NULL)
9900 	r = call_func(name, (int)STRLEN(name), rettv, argc, argv,
9901 				 curwin->w_cursor.lnum, curwin->w_cursor.lnum,
9902 					     &dummy, TRUE, partial, selfdict);
9903 
9904     /* Free the arguments. */
9905     while (argc > 0)
9906 	clear_tv(&argv[--argc]);
9907 
9908     return r;
9909 }
9910 
9911 /*
9912  * "call(func, arglist [, dict])" function
9913  */
9914     static void
9915 f_call(typval_T *argvars, typval_T *rettv)
9916 {
9917     char_u	*func;
9918     partial_T   *partial = NULL;
9919     dict_T	*selfdict = NULL;
9920 
9921     if (argvars[1].v_type != VAR_LIST)
9922     {
9923 	EMSG(_(e_listreq));
9924 	return;
9925     }
9926     if (argvars[1].vval.v_list == NULL)
9927 	return;
9928 
9929     if (argvars[0].v_type == VAR_FUNC)
9930 	func = argvars[0].vval.v_string;
9931     else if (argvars[0].v_type == VAR_PARTIAL)
9932     {
9933 	partial = argvars[0].vval.v_partial;
9934 	func = partial->pt_name;
9935     }
9936     else
9937 	func = get_tv_string(&argvars[0]);
9938     if (*func == NUL)
9939 	return;		/* type error or empty name */
9940 
9941     if (argvars[2].v_type != VAR_UNKNOWN)
9942     {
9943 	if (argvars[2].v_type != VAR_DICT)
9944 	{
9945 	    EMSG(_(e_dictreq));
9946 	    return;
9947 	}
9948 	selfdict = argvars[2].vval.v_dict;
9949     }
9950 
9951     (void)func_call(func, &argvars[1], partial, selfdict, rettv);
9952 }
9953 
9954 #ifdef FEAT_FLOAT
9955 /*
9956  * "ceil({float})" function
9957  */
9958     static void
9959 f_ceil(typval_T *argvars, typval_T *rettv)
9960 {
9961     float_T	f = 0.0;
9962 
9963     rettv->v_type = VAR_FLOAT;
9964     if (get_float_arg(argvars, &f) == OK)
9965 	rettv->vval.v_float = ceil(f);
9966     else
9967 	rettv->vval.v_float = 0.0;
9968 }
9969 #endif
9970 
9971 #ifdef FEAT_JOB_CHANNEL
9972 /*
9973  * "ch_close()" function
9974  */
9975     static void
9976 f_ch_close(typval_T *argvars, typval_T *rettv UNUSED)
9977 {
9978     channel_T *channel = get_channel_arg(&argvars[0], TRUE);
9979 
9980     if (channel != NULL)
9981     {
9982 	channel_close(channel, FALSE);
9983 	channel_clear(channel);
9984     }
9985 }
9986 
9987 /*
9988  * "ch_getbufnr()" function
9989  */
9990     static void
9991 f_ch_getbufnr(typval_T *argvars, typval_T *rettv)
9992 {
9993     channel_T *channel = get_channel_arg(&argvars[0], TRUE);
9994 
9995     rettv->vval.v_number = -1;
9996     if (channel != NULL)
9997     {
9998 	char_u	*what = get_tv_string(&argvars[1]);
9999 	int	part;
10000 
10001 	if (STRCMP(what, "err") == 0)
10002 	    part = PART_ERR;
10003 	else if (STRCMP(what, "out") == 0)
10004 	    part = PART_OUT;
10005 	else if (STRCMP(what, "in") == 0)
10006 	    part = PART_IN;
10007 	else
10008 	    part = PART_SOCK;
10009 	if (channel->ch_part[part].ch_buffer != NULL)
10010 	    rettv->vval.v_number = channel->ch_part[part].ch_buffer->b_fnum;
10011     }
10012 }
10013 
10014 /*
10015  * "ch_getjob()" function
10016  */
10017     static void
10018 f_ch_getjob(typval_T *argvars, typval_T *rettv)
10019 {
10020     channel_T *channel = get_channel_arg(&argvars[0], TRUE);
10021 
10022     if (channel != NULL)
10023     {
10024 	rettv->v_type = VAR_JOB;
10025 	rettv->vval.v_job = channel->ch_job;
10026 	if (channel->ch_job != NULL)
10027 	    ++channel->ch_job->jv_refcount;
10028     }
10029 }
10030 
10031 /*
10032  * "ch_log()" function
10033  */
10034     static void
10035 f_ch_log(typval_T *argvars, typval_T *rettv UNUSED)
10036 {
10037     char_u	*msg = get_tv_string(&argvars[0]);
10038     channel_T	*channel = NULL;
10039 
10040     if (argvars[1].v_type != VAR_UNKNOWN)
10041 	channel = get_channel_arg(&argvars[1], TRUE);
10042 
10043     ch_log(channel, (char *)msg);
10044 }
10045 
10046 /*
10047  * "ch_logfile()" function
10048  */
10049     static void
10050 f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED)
10051 {
10052     char_u *fname;
10053     char_u *opt = (char_u *)"";
10054     char_u buf[NUMBUFLEN];
10055 
10056     fname = get_tv_string(&argvars[0]);
10057     if (argvars[1].v_type == VAR_STRING)
10058 	opt = get_tv_string_buf(&argvars[1], buf);
10059     ch_logfile(fname, opt);
10060 }
10061 
10062 /*
10063  * "ch_open()" function
10064  */
10065     static void
10066 f_ch_open(typval_T *argvars, typval_T *rettv)
10067 {
10068     rettv->v_type = VAR_CHANNEL;
10069     rettv->vval.v_channel = channel_open_func(argvars);
10070 }
10071 
10072 /*
10073  * "ch_read()" function
10074  */
10075     static void
10076 f_ch_read(typval_T *argvars, typval_T *rettv)
10077 {
10078     common_channel_read(argvars, rettv, FALSE);
10079 }
10080 
10081 /*
10082  * "ch_readraw()" function
10083  */
10084     static void
10085 f_ch_readraw(typval_T *argvars, typval_T *rettv)
10086 {
10087     common_channel_read(argvars, rettv, TRUE);
10088 }
10089 
10090 /*
10091  * "ch_evalexpr()" function
10092  */
10093     static void
10094 f_ch_evalexpr(typval_T *argvars, typval_T *rettv)
10095 {
10096     ch_expr_common(argvars, rettv, TRUE);
10097 }
10098 
10099 /*
10100  * "ch_sendexpr()" function
10101  */
10102     static void
10103 f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
10104 {
10105     ch_expr_common(argvars, rettv, FALSE);
10106 }
10107 
10108 /*
10109  * "ch_evalraw()" function
10110  */
10111     static void
10112 f_ch_evalraw(typval_T *argvars, typval_T *rettv)
10113 {
10114     ch_raw_common(argvars, rettv, TRUE);
10115 }
10116 
10117 /*
10118  * "ch_sendraw()" function
10119  */
10120     static void
10121 f_ch_sendraw(typval_T *argvars, typval_T *rettv)
10122 {
10123     ch_raw_common(argvars, rettv, FALSE);
10124 }
10125 
10126 /*
10127  * "ch_setoptions()" function
10128  */
10129     static void
10130 f_ch_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
10131 {
10132     channel_T	*channel;
10133     jobopt_T	opt;
10134 
10135     channel = get_channel_arg(&argvars[0], TRUE);
10136     if (channel == NULL)
10137 	return;
10138     clear_job_options(&opt);
10139     if (get_job_options(&argvars[1], &opt,
10140 		JO_CB_ALL + JO_TIMEOUT_ALL + JO_MODE_ALL) == FAIL)
10141 	return;
10142     channel_set_options(channel, &opt);
10143 }
10144 
10145 /*
10146  * "ch_status()" function
10147  */
10148     static void
10149 f_ch_status(typval_T *argvars, typval_T *rettv)
10150 {
10151     channel_T	*channel;
10152 
10153     /* return an empty string by default */
10154     rettv->v_type = VAR_STRING;
10155     rettv->vval.v_string = NULL;
10156 
10157     channel = get_channel_arg(&argvars[0], FALSE);
10158     rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel));
10159 }
10160 #endif
10161 
10162 /*
10163  * "changenr()" function
10164  */
10165     static void
10166 f_changenr(typval_T *argvars UNUSED, typval_T *rettv)
10167 {
10168     rettv->vval.v_number = curbuf->b_u_seq_cur;
10169 }
10170 
10171 /*
10172  * "char2nr(string)" function
10173  */
10174     static void
10175 f_char2nr(typval_T *argvars, typval_T *rettv)
10176 {
10177 #ifdef FEAT_MBYTE
10178     if (has_mbyte)
10179     {
10180 	int	utf8 = 0;
10181 
10182 	if (argvars[1].v_type != VAR_UNKNOWN)
10183 	    utf8 = get_tv_number_chk(&argvars[1], NULL);
10184 
10185 	if (utf8)
10186 	    rettv->vval.v_number = (*utf_ptr2char)(get_tv_string(&argvars[0]));
10187 	else
10188 	    rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0]));
10189     }
10190     else
10191 #endif
10192     rettv->vval.v_number = get_tv_string(&argvars[0])[0];
10193 }
10194 
10195 /*
10196  * "cindent(lnum)" function
10197  */
10198     static void
10199 f_cindent(typval_T *argvars UNUSED, typval_T *rettv)
10200 {
10201 #ifdef FEAT_CINDENT
10202     pos_T	pos;
10203     linenr_T	lnum;
10204 
10205     pos = curwin->w_cursor;
10206     lnum = get_tv_lnum(argvars);
10207     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
10208     {
10209 	curwin->w_cursor.lnum = lnum;
10210 	rettv->vval.v_number = get_c_indent();
10211 	curwin->w_cursor = pos;
10212     }
10213     else
10214 #endif
10215 	rettv->vval.v_number = -1;
10216 }
10217 
10218 /*
10219  * "clearmatches()" function
10220  */
10221     static void
10222 f_clearmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10223 {
10224 #ifdef FEAT_SEARCH_EXTRA
10225     clear_matches(curwin);
10226 #endif
10227 }
10228 
10229 /*
10230  * "col(string)" function
10231  */
10232     static void
10233 f_col(typval_T *argvars, typval_T *rettv)
10234 {
10235     colnr_T	col = 0;
10236     pos_T	*fp;
10237     int		fnum = curbuf->b_fnum;
10238 
10239     fp = var2fpos(&argvars[0], FALSE, &fnum);
10240     if (fp != NULL && fnum == curbuf->b_fnum)
10241     {
10242 	if (fp->col == MAXCOL)
10243 	{
10244 	    /* '> can be MAXCOL, get the length of the line then */
10245 	    if (fp->lnum <= curbuf->b_ml.ml_line_count)
10246 		col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
10247 	    else
10248 		col = MAXCOL;
10249 	}
10250 	else
10251 	{
10252 	    col = fp->col + 1;
10253 #ifdef FEAT_VIRTUALEDIT
10254 	    /* col(".") when the cursor is on the NUL at the end of the line
10255 	     * because of "coladd" can be seen as an extra column. */
10256 	    if (virtual_active() && fp == &curwin->w_cursor)
10257 	    {
10258 		char_u	*p = ml_get_cursor();
10259 
10260 		if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p,
10261 				 curwin->w_virtcol - curwin->w_cursor.coladd))
10262 		{
10263 # ifdef FEAT_MBYTE
10264 		    int		l;
10265 
10266 		    if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL)
10267 			col += l;
10268 # else
10269 		    if (*p != NUL && p[1] == NUL)
10270 			++col;
10271 # endif
10272 		}
10273 	    }
10274 #endif
10275 	}
10276     }
10277     rettv->vval.v_number = col;
10278 }
10279 
10280 #if defined(FEAT_INS_EXPAND)
10281 /*
10282  * "complete()" function
10283  */
10284     static void
10285 f_complete(typval_T *argvars, typval_T *rettv UNUSED)
10286 {
10287     int	    startcol;
10288 
10289     if ((State & INSERT) == 0)
10290     {
10291 	EMSG(_("E785: complete() can only be used in Insert mode"));
10292 	return;
10293     }
10294 
10295     /* Check for undo allowed here, because if something was already inserted
10296      * the line was already saved for undo and this check isn't done. */
10297     if (!undo_allowed())
10298 	return;
10299 
10300     if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL)
10301     {
10302 	EMSG(_(e_invarg));
10303 	return;
10304     }
10305 
10306     startcol = get_tv_number_chk(&argvars[0], NULL);
10307     if (startcol <= 0)
10308 	return;
10309 
10310     set_completion(startcol - 1, argvars[1].vval.v_list);
10311 }
10312 
10313 /*
10314  * "complete_add()" function
10315  */
10316     static void
10317 f_complete_add(typval_T *argvars, typval_T *rettv)
10318 {
10319     rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0);
10320 }
10321 
10322 /*
10323  * "complete_check()" function
10324  */
10325     static void
10326 f_complete_check(typval_T *argvars UNUSED, typval_T *rettv)
10327 {
10328     int		saved = RedrawingDisabled;
10329 
10330     RedrawingDisabled = 0;
10331     ins_compl_check_keys(0);
10332     rettv->vval.v_number = compl_interrupted;
10333     RedrawingDisabled = saved;
10334 }
10335 #endif
10336 
10337 /*
10338  * "confirm(message, buttons[, default [, type]])" function
10339  */
10340     static void
10341 f_confirm(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10342 {
10343 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
10344     char_u	*message;
10345     char_u	*buttons = NULL;
10346     char_u	buf[NUMBUFLEN];
10347     char_u	buf2[NUMBUFLEN];
10348     int		def = 1;
10349     int		type = VIM_GENERIC;
10350     char_u	*typestr;
10351     int		error = FALSE;
10352 
10353     message = get_tv_string_chk(&argvars[0]);
10354     if (message == NULL)
10355 	error = TRUE;
10356     if (argvars[1].v_type != VAR_UNKNOWN)
10357     {
10358 	buttons = get_tv_string_buf_chk(&argvars[1], buf);
10359 	if (buttons == NULL)
10360 	    error = TRUE;
10361 	if (argvars[2].v_type != VAR_UNKNOWN)
10362 	{
10363 	    def = get_tv_number_chk(&argvars[2], &error);
10364 	    if (argvars[3].v_type != VAR_UNKNOWN)
10365 	    {
10366 		typestr = get_tv_string_buf_chk(&argvars[3], buf2);
10367 		if (typestr == NULL)
10368 		    error = TRUE;
10369 		else
10370 		{
10371 		    switch (TOUPPER_ASC(*typestr))
10372 		    {
10373 			case 'E': type = VIM_ERROR; break;
10374 			case 'Q': type = VIM_QUESTION; break;
10375 			case 'I': type = VIM_INFO; break;
10376 			case 'W': type = VIM_WARNING; break;
10377 			case 'G': type = VIM_GENERIC; break;
10378 		    }
10379 		}
10380 	    }
10381 	}
10382     }
10383 
10384     if (buttons == NULL || *buttons == NUL)
10385 	buttons = (char_u *)_("&Ok");
10386 
10387     if (!error)
10388 	rettv->vval.v_number = do_dialog(type, NULL, message, buttons,
10389 							    def, NULL, FALSE);
10390 #endif
10391 }
10392 
10393 /*
10394  * "copy()" function
10395  */
10396     static void
10397 f_copy(typval_T *argvars, typval_T *rettv)
10398 {
10399     item_copy(&argvars[0], rettv, FALSE, 0);
10400 }
10401 
10402 #ifdef FEAT_FLOAT
10403 /*
10404  * "cos()" function
10405  */
10406     static void
10407 f_cos(typval_T *argvars, typval_T *rettv)
10408 {
10409     float_T	f = 0.0;
10410 
10411     rettv->v_type = VAR_FLOAT;
10412     if (get_float_arg(argvars, &f) == OK)
10413 	rettv->vval.v_float = cos(f);
10414     else
10415 	rettv->vval.v_float = 0.0;
10416 }
10417 
10418 /*
10419  * "cosh()" function
10420  */
10421     static void
10422 f_cosh(typval_T *argvars, typval_T *rettv)
10423 {
10424     float_T	f = 0.0;
10425 
10426     rettv->v_type = VAR_FLOAT;
10427     if (get_float_arg(argvars, &f) == OK)
10428 	rettv->vval.v_float = cosh(f);
10429     else
10430 	rettv->vval.v_float = 0.0;
10431 }
10432 #endif
10433 
10434 /*
10435  * "count()" function
10436  */
10437     static void
10438 f_count(typval_T *argvars, typval_T *rettv)
10439 {
10440     long	n = 0;
10441     int		ic = FALSE;
10442 
10443     if (argvars[0].v_type == VAR_LIST)
10444     {
10445 	listitem_T	*li;
10446 	list_T		*l;
10447 	long		idx;
10448 
10449 	if ((l = argvars[0].vval.v_list) != NULL)
10450 	{
10451 	    li = l->lv_first;
10452 	    if (argvars[2].v_type != VAR_UNKNOWN)
10453 	    {
10454 		int error = FALSE;
10455 
10456 		ic = get_tv_number_chk(&argvars[2], &error);
10457 		if (argvars[3].v_type != VAR_UNKNOWN)
10458 		{
10459 		    idx = get_tv_number_chk(&argvars[3], &error);
10460 		    if (!error)
10461 		    {
10462 			li = list_find(l, idx);
10463 			if (li == NULL)
10464 			    EMSGN(_(e_listidx), idx);
10465 		    }
10466 		}
10467 		if (error)
10468 		    li = NULL;
10469 	    }
10470 
10471 	    for ( ; li != NULL; li = li->li_next)
10472 		if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE))
10473 		    ++n;
10474 	}
10475     }
10476     else if (argvars[0].v_type == VAR_DICT)
10477     {
10478 	int		todo;
10479 	dict_T		*d;
10480 	hashitem_T	*hi;
10481 
10482 	if ((d = argvars[0].vval.v_dict) != NULL)
10483 	{
10484 	    int error = FALSE;
10485 
10486 	    if (argvars[2].v_type != VAR_UNKNOWN)
10487 	    {
10488 		ic = get_tv_number_chk(&argvars[2], &error);
10489 		if (argvars[3].v_type != VAR_UNKNOWN)
10490 		    EMSG(_(e_invarg));
10491 	    }
10492 
10493 	    todo = error ? 0 : (int)d->dv_hashtab.ht_used;
10494 	    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
10495 	    {
10496 		if (!HASHITEM_EMPTY(hi))
10497 		{
10498 		    --todo;
10499 		    if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE))
10500 			++n;
10501 		}
10502 	    }
10503 	}
10504     }
10505     else
10506 	EMSG2(_(e_listdictarg), "count()");
10507     rettv->vval.v_number = n;
10508 }
10509 
10510 /*
10511  * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
10512  *
10513  * Checks the existence of a cscope connection.
10514  */
10515     static void
10516 f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10517 {
10518 #ifdef FEAT_CSCOPE
10519     int		num = 0;
10520     char_u	*dbpath = NULL;
10521     char_u	*prepend = NULL;
10522     char_u	buf[NUMBUFLEN];
10523 
10524     if (argvars[0].v_type != VAR_UNKNOWN
10525 	    && argvars[1].v_type != VAR_UNKNOWN)
10526     {
10527 	num = (int)get_tv_number(&argvars[0]);
10528 	dbpath = get_tv_string(&argvars[1]);
10529 	if (argvars[2].v_type != VAR_UNKNOWN)
10530 	    prepend = get_tv_string_buf(&argvars[2], buf);
10531     }
10532 
10533     rettv->vval.v_number = cs_connection(num, dbpath, prepend);
10534 #endif
10535 }
10536 
10537 /*
10538  * "cursor(lnum, col)" function, or
10539  * "cursor(list)"
10540  *
10541  * Moves the cursor to the specified line and column.
10542  * Returns 0 when the position could be set, -1 otherwise.
10543  */
10544     static void
10545 f_cursor(typval_T *argvars, typval_T *rettv)
10546 {
10547     long	line, col;
10548 #ifdef FEAT_VIRTUALEDIT
10549     long	coladd = 0;
10550 #endif
10551     int		set_curswant = TRUE;
10552 
10553     rettv->vval.v_number = -1;
10554     if (argvars[1].v_type == VAR_UNKNOWN)
10555     {
10556 	pos_T	    pos;
10557 	colnr_T	    curswant = -1;
10558 
10559 	if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL)
10560 	{
10561 	    EMSG(_(e_invarg));
10562 	    return;
10563 	}
10564 	line = pos.lnum;
10565 	col = pos.col;
10566 #ifdef FEAT_VIRTUALEDIT
10567 	coladd = pos.coladd;
10568 #endif
10569 	if (curswant >= 0)
10570 	{
10571 	    curwin->w_curswant = curswant - 1;
10572 	    set_curswant = FALSE;
10573 	}
10574     }
10575     else
10576     {
10577 	line = get_tv_lnum(argvars);
10578 	col = get_tv_number_chk(&argvars[1], NULL);
10579 #ifdef FEAT_VIRTUALEDIT
10580 	if (argvars[2].v_type != VAR_UNKNOWN)
10581 	    coladd = get_tv_number_chk(&argvars[2], NULL);
10582 #endif
10583     }
10584     if (line < 0 || col < 0
10585 #ifdef FEAT_VIRTUALEDIT
10586 			    || coladd < 0
10587 #endif
10588 	    )
10589 	return;		/* type error; errmsg already given */
10590     if (line > 0)
10591 	curwin->w_cursor.lnum = line;
10592     if (col > 0)
10593 	curwin->w_cursor.col = col - 1;
10594 #ifdef FEAT_VIRTUALEDIT
10595     curwin->w_cursor.coladd = coladd;
10596 #endif
10597 
10598     /* Make sure the cursor is in a valid position. */
10599     check_cursor();
10600 #ifdef FEAT_MBYTE
10601     /* Correct cursor for multi-byte character. */
10602     if (has_mbyte)
10603 	mb_adjust_cursor();
10604 #endif
10605 
10606     curwin->w_set_curswant = set_curswant;
10607     rettv->vval.v_number = 0;
10608 }
10609 
10610 /*
10611  * "deepcopy()" function
10612  */
10613     static void
10614 f_deepcopy(typval_T *argvars, typval_T *rettv)
10615 {
10616     int		noref = 0;
10617 
10618     if (argvars[1].v_type != VAR_UNKNOWN)
10619 	noref = get_tv_number_chk(&argvars[1], NULL);
10620     if (noref < 0 || noref > 1)
10621 	EMSG(_(e_invarg));
10622     else
10623     {
10624 	current_copyID += COPYID_INC;
10625 	item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0);
10626     }
10627 }
10628 
10629 /*
10630  * "delete()" function
10631  */
10632     static void
10633 f_delete(typval_T *argvars, typval_T *rettv)
10634 {
10635     char_u	nbuf[NUMBUFLEN];
10636     char_u	*name;
10637     char_u	*flags;
10638 
10639     rettv->vval.v_number = -1;
10640     if (check_restricted() || check_secure())
10641 	return;
10642 
10643     name = get_tv_string(&argvars[0]);
10644     if (name == NULL || *name == NUL)
10645     {
10646 	EMSG(_(e_invarg));
10647 	return;
10648     }
10649 
10650     if (argvars[1].v_type != VAR_UNKNOWN)
10651 	flags = get_tv_string_buf(&argvars[1], nbuf);
10652     else
10653 	flags = (char_u *)"";
10654 
10655     if (*flags == NUL)
10656 	/* delete a file */
10657 	rettv->vval.v_number = mch_remove(name) == 0 ? 0 : -1;
10658     else if (STRCMP(flags, "d") == 0)
10659 	/* delete an empty directory */
10660 	rettv->vval.v_number = mch_rmdir(name) == 0 ? 0 : -1;
10661     else if (STRCMP(flags, "rf") == 0)
10662 	/* delete a directory recursively */
10663 	rettv->vval.v_number = delete_recursive(name);
10664     else
10665 	EMSG2(_(e_invexpr2), flags);
10666 }
10667 
10668 /*
10669  * "did_filetype()" function
10670  */
10671     static void
10672 f_did_filetype(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10673 {
10674 #ifdef FEAT_AUTOCMD
10675     rettv->vval.v_number = did_filetype;
10676 #endif
10677 }
10678 
10679 /*
10680  * "diff_filler()" function
10681  */
10682     static void
10683 f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10684 {
10685 #ifdef FEAT_DIFF
10686     rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars));
10687 #endif
10688 }
10689 
10690 /*
10691  * "diff_hlID()" function
10692  */
10693     static void
10694 f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10695 {
10696 #ifdef FEAT_DIFF
10697     linenr_T		lnum = get_tv_lnum(argvars);
10698     static linenr_T	prev_lnum = 0;
10699     static int		changedtick = 0;
10700     static int		fnum = 0;
10701     static int		change_start = 0;
10702     static int		change_end = 0;
10703     static hlf_T	hlID = (hlf_T)0;
10704     int			filler_lines;
10705     int			col;
10706 
10707     if (lnum < 0)	/* ignore type error in {lnum} arg */
10708 	lnum = 0;
10709     if (lnum != prev_lnum
10710 	    || changedtick != curbuf->b_changedtick
10711 	    || fnum != curbuf->b_fnum)
10712     {
10713 	/* New line, buffer, change: need to get the values. */
10714 	filler_lines = diff_check(curwin, lnum);
10715 	if (filler_lines < 0)
10716 	{
10717 	    if (filler_lines == -1)
10718 	    {
10719 		change_start = MAXCOL;
10720 		change_end = -1;
10721 		if (diff_find_change(curwin, lnum, &change_start, &change_end))
10722 		    hlID = HLF_ADD;	/* added line */
10723 		else
10724 		    hlID = HLF_CHD;	/* changed line */
10725 	    }
10726 	    else
10727 		hlID = HLF_ADD;	/* added line */
10728 	}
10729 	else
10730 	    hlID = (hlf_T)0;
10731 	prev_lnum = lnum;
10732 	changedtick = curbuf->b_changedtick;
10733 	fnum = curbuf->b_fnum;
10734     }
10735 
10736     if (hlID == HLF_CHD || hlID == HLF_TXD)
10737     {
10738 	col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */
10739 	if (col >= change_start && col <= change_end)
10740 	    hlID = HLF_TXD;			/* changed text */
10741 	else
10742 	    hlID = HLF_CHD;			/* changed line */
10743     }
10744     rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID;
10745 #endif
10746 }
10747 
10748 /*
10749  * "disable_char_avail_for_testing({expr})" function
10750  */
10751     static void
10752 f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv UNUSED)
10753 {
10754     disable_char_avail_for_testing = get_tv_number(&argvars[0]);
10755 }
10756 
10757 /*
10758  * "empty({expr})" function
10759  */
10760     static void
10761 f_empty(typval_T *argvars, typval_T *rettv)
10762 {
10763     int		n = FALSE;
10764 
10765     switch (argvars[0].v_type)
10766     {
10767 	case VAR_STRING:
10768 	case VAR_FUNC:
10769 	    n = argvars[0].vval.v_string == NULL
10770 					  || *argvars[0].vval.v_string == NUL;
10771 	    break;
10772 	case VAR_PARTIAL:
10773 	    n = FALSE;
10774 	    break;
10775 	case VAR_NUMBER:
10776 	    n = argvars[0].vval.v_number == 0;
10777 	    break;
10778 	case VAR_FLOAT:
10779 #ifdef FEAT_FLOAT
10780 	    n = argvars[0].vval.v_float == 0.0;
10781 	    break;
10782 #endif
10783 	case VAR_LIST:
10784 	    n = argvars[0].vval.v_list == NULL
10785 				  || argvars[0].vval.v_list->lv_first == NULL;
10786 	    break;
10787 	case VAR_DICT:
10788 	    n = argvars[0].vval.v_dict == NULL
10789 			|| argvars[0].vval.v_dict->dv_hashtab.ht_used == 0;
10790 	    break;
10791 	case VAR_SPECIAL:
10792 	    n = argvars[0].vval.v_number != VVAL_TRUE;
10793 	    break;
10794 
10795 	case VAR_JOB:
10796 #ifdef FEAT_JOB_CHANNEL
10797 	    n = argvars[0].vval.v_job == NULL
10798 			   || argvars[0].vval.v_job->jv_status != JOB_STARTED;
10799 	    break;
10800 #endif
10801 	case VAR_CHANNEL:
10802 #ifdef FEAT_JOB_CHANNEL
10803 	    n = argvars[0].vval.v_channel == NULL
10804 			       || !channel_is_open(argvars[0].vval.v_channel);
10805 	    break;
10806 #endif
10807 	case VAR_UNKNOWN:
10808 	    EMSG2(_(e_intern2), "f_empty(UNKNOWN)");
10809 	    n = TRUE;
10810 	    break;
10811     }
10812 
10813     rettv->vval.v_number = n;
10814 }
10815 
10816 /*
10817  * "escape({string}, {chars})" function
10818  */
10819     static void
10820 f_escape(typval_T *argvars, typval_T *rettv)
10821 {
10822     char_u	buf[NUMBUFLEN];
10823 
10824     rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]),
10825 					 get_tv_string_buf(&argvars[1], buf));
10826     rettv->v_type = VAR_STRING;
10827 }
10828 
10829 /*
10830  * "eval()" function
10831  */
10832     static void
10833 f_eval(typval_T *argvars, typval_T *rettv)
10834 {
10835     char_u	*s, *p;
10836 
10837     s = get_tv_string_chk(&argvars[0]);
10838     if (s != NULL)
10839 	s = skipwhite(s);
10840 
10841     p = s;
10842     if (s == NULL || eval1(&s, rettv, TRUE) == FAIL)
10843     {
10844 	if (p != NULL && !aborting())
10845 	    EMSG2(_(e_invexpr2), p);
10846 	need_clr_eos = FALSE;
10847 	rettv->v_type = VAR_NUMBER;
10848 	rettv->vval.v_number = 0;
10849     }
10850     else if (*s != NUL)
10851 	EMSG(_(e_trailing));
10852 }
10853 
10854 /*
10855  * "eventhandler()" function
10856  */
10857     static void
10858 f_eventhandler(typval_T *argvars UNUSED, typval_T *rettv)
10859 {
10860     rettv->vval.v_number = vgetc_busy;
10861 }
10862 
10863 /*
10864  * "executable()" function
10865  */
10866     static void
10867 f_executable(typval_T *argvars, typval_T *rettv)
10868 {
10869     char_u *name = get_tv_string(&argvars[0]);
10870 
10871     /* Check in $PATH and also check directly if there is a directory name. */
10872     rettv->vval.v_number = mch_can_exe(name, NULL, TRUE)
10873 		 || (gettail(name) != name && mch_can_exe(name, NULL, FALSE));
10874 }
10875 
10876 /*
10877  * "exepath()" function
10878  */
10879     static void
10880 f_exepath(typval_T *argvars, typval_T *rettv)
10881 {
10882     char_u *p = NULL;
10883 
10884     (void)mch_can_exe(get_tv_string(&argvars[0]), &p, TRUE);
10885     rettv->v_type = VAR_STRING;
10886     rettv->vval.v_string = p;
10887 }
10888 
10889 /*
10890  * "exists()" function
10891  */
10892     static void
10893 f_exists(typval_T *argvars, typval_T *rettv)
10894 {
10895     char_u	*p;
10896     char_u	*name;
10897     int		n = FALSE;
10898     int		len = 0;
10899 
10900     p = get_tv_string(&argvars[0]);
10901     if (*p == '$')			/* environment variable */
10902     {
10903 	/* first try "normal" environment variables (fast) */
10904 	if (mch_getenv(p + 1) != NULL)
10905 	    n = TRUE;
10906 	else
10907 	{
10908 	    /* try expanding things like $VIM and ${HOME} */
10909 	    p = expand_env_save(p);
10910 	    if (p != NULL && *p != '$')
10911 		n = TRUE;
10912 	    vim_free(p);
10913 	}
10914     }
10915     else if (*p == '&' || *p == '+')			/* option */
10916     {
10917 	n = (get_option_tv(&p, NULL, TRUE) == OK);
10918 	if (*skipwhite(p) != NUL)
10919 	    n = FALSE;			/* trailing garbage */
10920     }
10921     else if (*p == '*')			/* internal or user defined function */
10922     {
10923 	n = function_exists(p + 1);
10924     }
10925     else if (*p == ':')
10926     {
10927 	n = cmd_exists(p + 1);
10928     }
10929     else if (*p == '#')
10930     {
10931 #ifdef FEAT_AUTOCMD
10932 	if (p[1] == '#')
10933 	    n = autocmd_supported(p + 2);
10934 	else
10935 	    n = au_exists(p + 1);
10936 #endif
10937     }
10938     else				/* internal variable */
10939     {
10940 	char_u	    *tofree;
10941 	typval_T    tv;
10942 
10943 	/* get_name_len() takes care of expanding curly braces */
10944 	name = p;
10945 	len = get_name_len(&p, &tofree, TRUE, FALSE);
10946 	if (len > 0)
10947 	{
10948 	    if (tofree != NULL)
10949 		name = tofree;
10950 	    n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK);
10951 	    if (n)
10952 	    {
10953 		/* handle d.key, l[idx], f(expr) */
10954 		n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK);
10955 		if (n)
10956 		    clear_tv(&tv);
10957 	    }
10958 	}
10959 	if (*p != NUL)
10960 	    n = FALSE;
10961 
10962 	vim_free(tofree);
10963     }
10964 
10965     rettv->vval.v_number = n;
10966 }
10967 
10968 #ifdef FEAT_FLOAT
10969 /*
10970  * "exp()" function
10971  */
10972     static void
10973 f_exp(typval_T *argvars, typval_T *rettv)
10974 {
10975     float_T	f = 0.0;
10976 
10977     rettv->v_type = VAR_FLOAT;
10978     if (get_float_arg(argvars, &f) == OK)
10979 	rettv->vval.v_float = exp(f);
10980     else
10981 	rettv->vval.v_float = 0.0;
10982 }
10983 #endif
10984 
10985 /*
10986  * "expand()" function
10987  */
10988     static void
10989 f_expand(typval_T *argvars, typval_T *rettv)
10990 {
10991     char_u	*s;
10992     int		len;
10993     char_u	*errormsg;
10994     int		options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
10995     expand_T	xpc;
10996     int		error = FALSE;
10997     char_u	*result;
10998 
10999     rettv->v_type = VAR_STRING;
11000     if (argvars[1].v_type != VAR_UNKNOWN
11001 	    && argvars[2].v_type != VAR_UNKNOWN
11002 	    && get_tv_number_chk(&argvars[2], &error)
11003 	    && !error)
11004     {
11005 	rettv->v_type = VAR_LIST;
11006 	rettv->vval.v_list = NULL;
11007     }
11008 
11009     s = get_tv_string(&argvars[0]);
11010     if (*s == '%' || *s == '#' || *s == '<')
11011     {
11012 	++emsg_off;
11013 	result = eval_vars(s, s, &len, NULL, &errormsg, NULL);
11014 	--emsg_off;
11015 	if (rettv->v_type == VAR_LIST)
11016 	{
11017 	    if (rettv_list_alloc(rettv) != FAIL && result != NULL)
11018 		list_append_string(rettv->vval.v_list, result, -1);
11019 	    else
11020 		vim_free(result);
11021 	}
11022 	else
11023 	    rettv->vval.v_string = result;
11024     }
11025     else
11026     {
11027 	/* When the optional second argument is non-zero, don't remove matches
11028 	 * for 'wildignore' and don't put matches for 'suffixes' at the end. */
11029 	if (argvars[1].v_type != VAR_UNKNOWN
11030 				    && get_tv_number_chk(&argvars[1], &error))
11031 	    options |= WILD_KEEP_ALL;
11032 	if (!error)
11033 	{
11034 	    ExpandInit(&xpc);
11035 	    xpc.xp_context = EXPAND_FILES;
11036 	    if (p_wic)
11037 		options += WILD_ICASE;
11038 	    if (rettv->v_type == VAR_STRING)
11039 		rettv->vval.v_string = ExpandOne(&xpc, s, NULL,
11040 							   options, WILD_ALL);
11041 	    else if (rettv_list_alloc(rettv) != FAIL)
11042 	    {
11043 		int i;
11044 
11045 		ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP);
11046 		for (i = 0; i < xpc.xp_numfiles; i++)
11047 		    list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
11048 		ExpandCleanup(&xpc);
11049 	    }
11050 	}
11051 	else
11052 	    rettv->vval.v_string = NULL;
11053     }
11054 }
11055 
11056 /*
11057  * Go over all entries in "d2" and add them to "d1".
11058  * When "action" is "error" then a duplicate key is an error.
11059  * When "action" is "force" then a duplicate key is overwritten.
11060  * Otherwise duplicate keys are ignored ("action" is "keep").
11061  */
11062     void
11063 dict_extend(dict_T *d1, dict_T *d2, char_u *action)
11064 {
11065     dictitem_T	*di1;
11066     hashitem_T	*hi2;
11067     int		todo;
11068     char_u	*arg_errmsg = (char_u *)N_("extend() argument");
11069 
11070     todo = (int)d2->dv_hashtab.ht_used;
11071     for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2)
11072     {
11073 	if (!HASHITEM_EMPTY(hi2))
11074 	{
11075 	    --todo;
11076 	    di1 = dict_find(d1, hi2->hi_key, -1);
11077 	    if (d1->dv_scope != 0)
11078 	    {
11079 		/* Disallow replacing a builtin function in l: and g:.
11080 		 * Check the key to be valid when adding to any
11081 		 * scope. */
11082 		if (d1->dv_scope == VAR_DEF_SCOPE
11083 			&& HI2DI(hi2)->di_tv.v_type == VAR_FUNC
11084 			&& var_check_func_name(hi2->hi_key,
11085 							 di1 == NULL))
11086 		    break;
11087 		if (!valid_varname(hi2->hi_key))
11088 		    break;
11089 	    }
11090 	    if (di1 == NULL)
11091 	    {
11092 		di1 = dictitem_copy(HI2DI(hi2));
11093 		if (di1 != NULL && dict_add(d1, di1) == FAIL)
11094 		    dictitem_free(di1);
11095 	    }
11096 	    else if (*action == 'e')
11097 	    {
11098 		EMSG2(_("E737: Key already exists: %s"), hi2->hi_key);
11099 		break;
11100 	    }
11101 	    else if (*action == 'f' && HI2DI(hi2) != di1)
11102 	    {
11103 		if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, TRUE)
11104 		      || var_check_ro(di1->di_flags, arg_errmsg, TRUE))
11105 		    break;
11106 		clear_tv(&di1->di_tv);
11107 		copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv);
11108 	    }
11109 	}
11110     }
11111 }
11112 
11113 /*
11114  * "extend(list, list [, idx])" function
11115  * "extend(dict, dict [, action])" function
11116  */
11117     static void
11118 f_extend(typval_T *argvars, typval_T *rettv)
11119 {
11120     char_u      *arg_errmsg = (char_u *)N_("extend() argument");
11121 
11122     if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
11123     {
11124 	list_T		*l1, *l2;
11125 	listitem_T	*item;
11126 	long		before;
11127 	int		error = FALSE;
11128 
11129 	l1 = argvars[0].vval.v_list;
11130 	l2 = argvars[1].vval.v_list;
11131 	if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, TRUE)
11132 		&& l2 != NULL)
11133 	{
11134 	    if (argvars[2].v_type != VAR_UNKNOWN)
11135 	    {
11136 		before = get_tv_number_chk(&argvars[2], &error);
11137 		if (error)
11138 		    return;		/* type error; errmsg already given */
11139 
11140 		if (before == l1->lv_len)
11141 		    item = NULL;
11142 		else
11143 		{
11144 		    item = list_find(l1, before);
11145 		    if (item == NULL)
11146 		    {
11147 			EMSGN(_(e_listidx), before);
11148 			return;
11149 		    }
11150 		}
11151 	    }
11152 	    else
11153 		item = NULL;
11154 	    list_extend(l1, l2, item);
11155 
11156 	    copy_tv(&argvars[0], rettv);
11157 	}
11158     }
11159     else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
11160     {
11161 	dict_T	*d1, *d2;
11162 	char_u	*action;
11163 	int	i;
11164 
11165 	d1 = argvars[0].vval.v_dict;
11166 	d2 = argvars[1].vval.v_dict;
11167 	if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, TRUE)
11168 		&& d2 != NULL)
11169 	{
11170 	    /* Check the third argument. */
11171 	    if (argvars[2].v_type != VAR_UNKNOWN)
11172 	    {
11173 		static char *(av[]) = {"keep", "force", "error"};
11174 
11175 		action = get_tv_string_chk(&argvars[2]);
11176 		if (action == NULL)
11177 		    return;		/* type error; errmsg already given */
11178 		for (i = 0; i < 3; ++i)
11179 		    if (STRCMP(action, av[i]) == 0)
11180 			break;
11181 		if (i == 3)
11182 		{
11183 		    EMSG2(_(e_invarg2), action);
11184 		    return;
11185 		}
11186 	    }
11187 	    else
11188 		action = (char_u *)"force";
11189 
11190 	    dict_extend(d1, d2, action);
11191 
11192 	    copy_tv(&argvars[0], rettv);
11193 	}
11194     }
11195     else
11196 	EMSG2(_(e_listdictarg), "extend()");
11197 }
11198 
11199 /*
11200  * "feedkeys()" function
11201  */
11202     static void
11203 f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED)
11204 {
11205     int		remap = TRUE;
11206     int		insert = FALSE;
11207     char_u	*keys, *flags;
11208     char_u	nbuf[NUMBUFLEN];
11209     int		typed = FALSE;
11210     int		execute = FALSE;
11211     char_u	*keys_esc;
11212 
11213     /* This is not allowed in the sandbox.  If the commands would still be
11214      * executed in the sandbox it would be OK, but it probably happens later,
11215      * when "sandbox" is no longer set. */
11216     if (check_secure())
11217 	return;
11218 
11219     keys = get_tv_string(&argvars[0]);
11220 
11221     if (argvars[1].v_type != VAR_UNKNOWN)
11222     {
11223 	flags = get_tv_string_buf(&argvars[1], nbuf);
11224 	for ( ; *flags != NUL; ++flags)
11225 	{
11226 	    switch (*flags)
11227 	    {
11228 		case 'n': remap = FALSE; break;
11229 		case 'm': remap = TRUE; break;
11230 		case 't': typed = TRUE; break;
11231 		case 'i': insert = TRUE; break;
11232 		case 'x': execute = TRUE; break;
11233 	    }
11234 	}
11235     }
11236 
11237     if (*keys != NUL || execute)
11238     {
11239 	/* Need to escape K_SPECIAL and CSI before putting the string in the
11240 	 * typeahead buffer. */
11241 	keys_esc = vim_strsave_escape_csi(keys);
11242 	if (keys_esc != NULL)
11243 	{
11244 	    ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
11245 				  insert ? 0 : typebuf.tb_len, !typed, FALSE);
11246 	    vim_free(keys_esc);
11247 	    if (vgetc_busy)
11248 		typebuf_was_filled = TRUE;
11249 	    if (execute)
11250 	    {
11251 		int save_msg_scroll = msg_scroll;
11252 
11253 		/* Avoid a 1 second delay when the keys start Insert mode. */
11254 		msg_scroll = FALSE;
11255 		exec_normal(TRUE);
11256 		msg_scroll |= save_msg_scroll;
11257 	    }
11258 	}
11259     }
11260 }
11261 
11262 /*
11263  * "filereadable()" function
11264  */
11265     static void
11266 f_filereadable(typval_T *argvars, typval_T *rettv)
11267 {
11268     int		fd;
11269     char_u	*p;
11270     int		n;
11271 
11272 #ifndef O_NONBLOCK
11273 # define O_NONBLOCK 0
11274 #endif
11275     p = get_tv_string(&argvars[0]);
11276     if (*p && !mch_isdir(p) && (fd = mch_open((char *)p,
11277 					      O_RDONLY | O_NONBLOCK, 0)) >= 0)
11278     {
11279 	n = TRUE;
11280 	close(fd);
11281     }
11282     else
11283 	n = FALSE;
11284 
11285     rettv->vval.v_number = n;
11286 }
11287 
11288 /*
11289  * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
11290  * rights to write into.
11291  */
11292     static void
11293 f_filewritable(typval_T *argvars, typval_T *rettv)
11294 {
11295     rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
11296 }
11297 
11298     static void
11299 findfilendir(
11300     typval_T	*argvars UNUSED,
11301     typval_T	*rettv,
11302     int		find_what UNUSED)
11303 {
11304 #ifdef FEAT_SEARCHPATH
11305     char_u	*fname;
11306     char_u	*fresult = NULL;
11307     char_u	*path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
11308     char_u	*p;
11309     char_u	pathbuf[NUMBUFLEN];
11310     int		count = 1;
11311     int		first = TRUE;
11312     int		error = FALSE;
11313 #endif
11314 
11315     rettv->vval.v_string = NULL;
11316     rettv->v_type = VAR_STRING;
11317 
11318 #ifdef FEAT_SEARCHPATH
11319     fname = get_tv_string(&argvars[0]);
11320 
11321     if (argvars[1].v_type != VAR_UNKNOWN)
11322     {
11323 	p = get_tv_string_buf_chk(&argvars[1], pathbuf);
11324 	if (p == NULL)
11325 	    error = TRUE;
11326 	else
11327 	{
11328 	    if (*p != NUL)
11329 		path = p;
11330 
11331 	    if (argvars[2].v_type != VAR_UNKNOWN)
11332 		count = get_tv_number_chk(&argvars[2], &error);
11333 	}
11334     }
11335 
11336     if (count < 0 && rettv_list_alloc(rettv) == FAIL)
11337 	error = TRUE;
11338 
11339     if (*fname != NUL && !error)
11340     {
11341 	do
11342 	{
11343 	    if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST)
11344 		vim_free(fresult);
11345 	    fresult = find_file_in_path_option(first ? fname : NULL,
11346 					       first ? (int)STRLEN(fname) : 0,
11347 					0, first, path,
11348 					find_what,
11349 					curbuf->b_ffname,
11350 					find_what == FINDFILE_DIR
11351 					    ? (char_u *)"" : curbuf->b_p_sua);
11352 	    first = FALSE;
11353 
11354 	    if (fresult != NULL && rettv->v_type == VAR_LIST)
11355 		list_append_string(rettv->vval.v_list, fresult, -1);
11356 
11357 	} while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL);
11358     }
11359 
11360     if (rettv->v_type == VAR_STRING)
11361 	rettv->vval.v_string = fresult;
11362 #endif
11363 }
11364 
11365 static void filter_map(typval_T *argvars, typval_T *rettv, int map);
11366 static int filter_map_one(typval_T *tv, char_u *expr, int map, int *remp);
11367 
11368 /*
11369  * Implementation of map() and filter().
11370  */
11371     static void
11372 filter_map(typval_T *argvars, typval_T *rettv, int map)
11373 {
11374     char_u	buf[NUMBUFLEN];
11375     char_u	*expr;
11376     listitem_T	*li, *nli;
11377     list_T	*l = NULL;
11378     dictitem_T	*di;
11379     hashtab_T	*ht;
11380     hashitem_T	*hi;
11381     dict_T	*d = NULL;
11382     typval_T	save_val;
11383     typval_T	save_key;
11384     int		rem;
11385     int		todo;
11386     char_u	*ermsg = (char_u *)(map ? "map()" : "filter()");
11387     char_u	*arg_errmsg = (char_u *)(map ? N_("map() argument")
11388 				   : N_("filter() argument"));
11389     int		save_did_emsg;
11390     int		idx = 0;
11391 
11392     if (argvars[0].v_type == VAR_LIST)
11393     {
11394 	if ((l = argvars[0].vval.v_list) == NULL
11395 	      || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TRUE)))
11396 	    return;
11397     }
11398     else if (argvars[0].v_type == VAR_DICT)
11399     {
11400 	if ((d = argvars[0].vval.v_dict) == NULL
11401 	      || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TRUE)))
11402 	    return;
11403     }
11404     else
11405     {
11406 	EMSG2(_(e_listdictarg), ermsg);
11407 	return;
11408     }
11409 
11410     expr = get_tv_string_buf_chk(&argvars[1], buf);
11411     /* On type errors, the preceding call has already displayed an error
11412      * message.  Avoid a misleading error message for an empty string that
11413      * was not passed as argument. */
11414     if (expr != NULL)
11415     {
11416 	prepare_vimvar(VV_VAL, &save_val);
11417 	expr = skipwhite(expr);
11418 
11419 	/* We reset "did_emsg" to be able to detect whether an error
11420 	 * occurred during evaluation of the expression. */
11421 	save_did_emsg = did_emsg;
11422 	did_emsg = FALSE;
11423 
11424 	prepare_vimvar(VV_KEY, &save_key);
11425 	if (argvars[0].v_type == VAR_DICT)
11426 	{
11427 	    vimvars[VV_KEY].vv_type = VAR_STRING;
11428 
11429 	    ht = &d->dv_hashtab;
11430 	    hash_lock(ht);
11431 	    todo = (int)ht->ht_used;
11432 	    for (hi = ht->ht_array; todo > 0; ++hi)
11433 	    {
11434 		if (!HASHITEM_EMPTY(hi))
11435 		{
11436 		    int r;
11437 
11438 		    --todo;
11439 		    di = HI2DI(hi);
11440 		    if (map &&
11441 			    (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TRUE)
11442 			    || var_check_ro(di->di_flags, arg_errmsg, TRUE)))
11443 			break;
11444 		    vimvars[VV_KEY].vv_str = vim_strsave(di->di_key);
11445 		    r = filter_map_one(&di->di_tv, expr, map, &rem);
11446 		    clear_tv(&vimvars[VV_KEY].vv_tv);
11447 		    if (r == FAIL || did_emsg)
11448 			break;
11449 		    if (!map && rem)
11450 		    {
11451 			if (var_check_fixed(di->di_flags, arg_errmsg, TRUE)
11452 			    || var_check_ro(di->di_flags, arg_errmsg, TRUE))
11453 			    break;
11454 			dictitem_remove(d, di);
11455 		    }
11456 		}
11457 	    }
11458 	    hash_unlock(ht);
11459 	}
11460 	else
11461 	{
11462 	    vimvars[VV_KEY].vv_type = VAR_NUMBER;
11463 
11464 	    for (li = l->lv_first; li != NULL; li = nli)
11465 	    {
11466 		if (map && tv_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE))
11467 		    break;
11468 		nli = li->li_next;
11469 		vimvars[VV_KEY].vv_nr = idx;
11470 		if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
11471 								  || did_emsg)
11472 		    break;
11473 		if (!map && rem)
11474 		    listitem_remove(l, li);
11475 		++idx;
11476 	    }
11477 	}
11478 
11479 	restore_vimvar(VV_KEY, &save_key);
11480 	restore_vimvar(VV_VAL, &save_val);
11481 
11482 	did_emsg |= save_did_emsg;
11483     }
11484 
11485     copy_tv(&argvars[0], rettv);
11486 }
11487 
11488     static int
11489 filter_map_one(typval_T *tv, char_u *expr, int map, int *remp)
11490 {
11491     typval_T	rettv;
11492     char_u	*s;
11493     int		retval = FAIL;
11494 
11495     copy_tv(tv, &vimvars[VV_VAL].vv_tv);
11496     s = expr;
11497     if (eval1(&s, &rettv, TRUE) == FAIL)
11498 	goto theend;
11499     if (*s != NUL)  /* check for trailing chars after expr */
11500     {
11501 	EMSG2(_(e_invexpr2), s);
11502 	clear_tv(&rettv);
11503 	goto theend;
11504     }
11505     if (map)
11506     {
11507 	/* map(): replace the list item value */
11508 	clear_tv(tv);
11509 	rettv.v_lock = 0;
11510 	*tv = rettv;
11511     }
11512     else
11513     {
11514 	int	    error = FALSE;
11515 
11516 	/* filter(): when expr is zero remove the item */
11517 	*remp = (get_tv_number_chk(&rettv, &error) == 0);
11518 	clear_tv(&rettv);
11519 	/* On type error, nothing has been removed; return FAIL to stop the
11520 	 * loop.  The error message was given by get_tv_number_chk(). */
11521 	if (error)
11522 	    goto theend;
11523     }
11524     retval = OK;
11525 theend:
11526     clear_tv(&vimvars[VV_VAL].vv_tv);
11527     return retval;
11528 }
11529 
11530 /*
11531  * "filter()" function
11532  */
11533     static void
11534 f_filter(typval_T *argvars, typval_T *rettv)
11535 {
11536     filter_map(argvars, rettv, FALSE);
11537 }
11538 
11539 /*
11540  * "finddir({fname}[, {path}[, {count}]])" function
11541  */
11542     static void
11543 f_finddir(typval_T *argvars, typval_T *rettv)
11544 {
11545     findfilendir(argvars, rettv, FINDFILE_DIR);
11546 }
11547 
11548 /*
11549  * "findfile({fname}[, {path}[, {count}]])" function
11550  */
11551     static void
11552 f_findfile(typval_T *argvars, typval_T *rettv)
11553 {
11554     findfilendir(argvars, rettv, FINDFILE_FILE);
11555 }
11556 
11557 #ifdef FEAT_FLOAT
11558 /*
11559  * "float2nr({float})" function
11560  */
11561     static void
11562 f_float2nr(typval_T *argvars, typval_T *rettv)
11563 {
11564     float_T	f = 0.0;
11565 
11566     if (get_float_arg(argvars, &f) == OK)
11567     {
11568 	if (f < -0x7fffffff)
11569 	    rettv->vval.v_number = -0x7fffffff;
11570 	else if (f > 0x7fffffff)
11571 	    rettv->vval.v_number = 0x7fffffff;
11572 	else
11573 	    rettv->vval.v_number = (varnumber_T)f;
11574     }
11575 }
11576 
11577 /*
11578  * "floor({float})" function
11579  */
11580     static void
11581 f_floor(typval_T *argvars, typval_T *rettv)
11582 {
11583     float_T	f = 0.0;
11584 
11585     rettv->v_type = VAR_FLOAT;
11586     if (get_float_arg(argvars, &f) == OK)
11587 	rettv->vval.v_float = floor(f);
11588     else
11589 	rettv->vval.v_float = 0.0;
11590 }
11591 
11592 /*
11593  * "fmod()" function
11594  */
11595     static void
11596 f_fmod(typval_T *argvars, typval_T *rettv)
11597 {
11598     float_T	fx = 0.0, fy = 0.0;
11599 
11600     rettv->v_type = VAR_FLOAT;
11601     if (get_float_arg(argvars, &fx) == OK
11602 				     && get_float_arg(&argvars[1], &fy) == OK)
11603 	rettv->vval.v_float = fmod(fx, fy);
11604     else
11605 	rettv->vval.v_float = 0.0;
11606 }
11607 #endif
11608 
11609 /*
11610  * "fnameescape({string})" function
11611  */
11612     static void
11613 f_fnameescape(typval_T *argvars, typval_T *rettv)
11614 {
11615     rettv->vval.v_string = vim_strsave_fnameescape(
11616 					   get_tv_string(&argvars[0]), FALSE);
11617     rettv->v_type = VAR_STRING;
11618 }
11619 
11620 /*
11621  * "fnamemodify({fname}, {mods})" function
11622  */
11623     static void
11624 f_fnamemodify(typval_T *argvars, typval_T *rettv)
11625 {
11626     char_u	*fname;
11627     char_u	*mods;
11628     int		usedlen = 0;
11629     int		len;
11630     char_u	*fbuf = NULL;
11631     char_u	buf[NUMBUFLEN];
11632 
11633     fname = get_tv_string_chk(&argvars[0]);
11634     mods = get_tv_string_buf_chk(&argvars[1], buf);
11635     if (fname == NULL || mods == NULL)
11636 	fname = NULL;
11637     else
11638     {
11639 	len = (int)STRLEN(fname);
11640 	(void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
11641     }
11642 
11643     rettv->v_type = VAR_STRING;
11644     if (fname == NULL)
11645 	rettv->vval.v_string = NULL;
11646     else
11647 	rettv->vval.v_string = vim_strnsave(fname, len);
11648     vim_free(fbuf);
11649 }
11650 
11651 static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end);
11652 
11653 /*
11654  * "foldclosed()" function
11655  */
11656     static void
11657 foldclosed_both(
11658     typval_T	*argvars UNUSED,
11659     typval_T	*rettv,
11660     int		end UNUSED)
11661 {
11662 #ifdef FEAT_FOLDING
11663     linenr_T	lnum;
11664     linenr_T	first, last;
11665 
11666     lnum = get_tv_lnum(argvars);
11667     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
11668     {
11669 	if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL))
11670 	{
11671 	    if (end)
11672 		rettv->vval.v_number = (varnumber_T)last;
11673 	    else
11674 		rettv->vval.v_number = (varnumber_T)first;
11675 	    return;
11676 	}
11677     }
11678 #endif
11679     rettv->vval.v_number = -1;
11680 }
11681 
11682 /*
11683  * "foldclosed()" function
11684  */
11685     static void
11686 f_foldclosed(typval_T *argvars, typval_T *rettv)
11687 {
11688     foldclosed_both(argvars, rettv, FALSE);
11689 }
11690 
11691 /*
11692  * "foldclosedend()" function
11693  */
11694     static void
11695 f_foldclosedend(typval_T *argvars, typval_T *rettv)
11696 {
11697     foldclosed_both(argvars, rettv, TRUE);
11698 }
11699 
11700 /*
11701  * "foldlevel()" function
11702  */
11703     static void
11704 f_foldlevel(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
11705 {
11706 #ifdef FEAT_FOLDING
11707     linenr_T	lnum;
11708 
11709     lnum = get_tv_lnum(argvars);
11710     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
11711 	rettv->vval.v_number = foldLevel(lnum);
11712 #endif
11713 }
11714 
11715 /*
11716  * "foldtext()" function
11717  */
11718     static void
11719 f_foldtext(typval_T *argvars UNUSED, typval_T *rettv)
11720 {
11721 #ifdef FEAT_FOLDING
11722     linenr_T	lnum;
11723     char_u	*s;
11724     char_u	*r;
11725     int		len;
11726     char	*txt;
11727 #endif
11728 
11729     rettv->v_type = VAR_STRING;
11730     rettv->vval.v_string = NULL;
11731 #ifdef FEAT_FOLDING
11732     if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0
11733 	    && (linenr_T)vimvars[VV_FOLDEND].vv_nr
11734 						 <= curbuf->b_ml.ml_line_count
11735 	    && vimvars[VV_FOLDDASHES].vv_str != NULL)
11736     {
11737 	/* Find first non-empty line in the fold. */
11738 	lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr;
11739 	while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr)
11740 	{
11741 	    if (!linewhite(lnum))
11742 		break;
11743 	    ++lnum;
11744 	}
11745 
11746 	/* Find interesting text in this line. */
11747 	s = skipwhite(ml_get(lnum));
11748 	/* skip C comment-start */
11749 	if (s[0] == '/' && (s[1] == '*' || s[1] == '/'))
11750 	{
11751 	    s = skipwhite(s + 2);
11752 	    if (*skipwhite(s) == NUL
11753 			    && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr)
11754 	    {
11755 		s = skipwhite(ml_get(lnum + 1));
11756 		if (*s == '*')
11757 		    s = skipwhite(s + 1);
11758 	    }
11759 	}
11760 	txt = _("+-%s%3ld lines: ");
11761 	r = alloc((unsigned)(STRLEN(txt)
11762 		    + STRLEN(vimvars[VV_FOLDDASHES].vv_str)    /* for %s */
11763 		    + 20				    /* for %3ld */
11764 		    + STRLEN(s)));			    /* concatenated */
11765 	if (r != NULL)
11766 	{
11767 	    sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str,
11768 		    (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr
11769 				- (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1));
11770 	    len = (int)STRLEN(r);
11771 	    STRCAT(r, s);
11772 	    /* remove 'foldmarker' and 'commentstring' */
11773 	    foldtext_cleanup(r + len);
11774 	    rettv->vval.v_string = r;
11775 	}
11776     }
11777 #endif
11778 }
11779 
11780 /*
11781  * "foldtextresult(lnum)" function
11782  */
11783     static void
11784 f_foldtextresult(typval_T *argvars UNUSED, typval_T *rettv)
11785 {
11786 #ifdef FEAT_FOLDING
11787     linenr_T	lnum;
11788     char_u	*text;
11789     char_u	buf[51];
11790     foldinfo_T  foldinfo;
11791     int		fold_count;
11792 #endif
11793 
11794     rettv->v_type = VAR_STRING;
11795     rettv->vval.v_string = NULL;
11796 #ifdef FEAT_FOLDING
11797     lnum = get_tv_lnum(argvars);
11798     /* treat illegal types and illegal string values for {lnum} the same */
11799     if (lnum < 0)
11800 	lnum = 0;
11801     fold_count = foldedCount(curwin, lnum, &foldinfo);
11802     if (fold_count > 0)
11803     {
11804 	text = get_foldtext(curwin, lnum, lnum + fold_count - 1,
11805 							      &foldinfo, buf);
11806 	if (text == buf)
11807 	    text = vim_strsave(text);
11808 	rettv->vval.v_string = text;
11809     }
11810 #endif
11811 }
11812 
11813 /*
11814  * "foreground()" function
11815  */
11816     static void
11817 f_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
11818 {
11819 #ifdef FEAT_GUI
11820     if (gui.in_use)
11821 	gui_mch_set_foreground();
11822 #else
11823 # ifdef WIN32
11824     win32_set_foreground();
11825 # endif
11826 #endif
11827 }
11828 
11829 /*
11830  * "function()" function
11831  */
11832     static void
11833 f_function(typval_T *argvars, typval_T *rettv)
11834 {
11835     char_u	*s;
11836     char_u	*name;
11837     int		use_string = FALSE;
11838     partial_T   *arg_pt = NULL;
11839 
11840     if (argvars[0].v_type == VAR_FUNC)
11841     {
11842 	/* function(MyFunc, [arg], dict) */
11843 	s = argvars[0].vval.v_string;
11844     }
11845     else if (argvars[0].v_type == VAR_PARTIAL
11846 					 && argvars[0].vval.v_partial != NULL)
11847     {
11848 	/* function(dict.MyFunc, [arg]) */
11849 	arg_pt = argvars[0].vval.v_partial;
11850 	s = arg_pt->pt_name;
11851     }
11852     else
11853     {
11854 	/* function('MyFunc', [arg], dict) */
11855 	s = get_tv_string(&argvars[0]);
11856 	use_string = TRUE;
11857     }
11858 
11859     if (s == NULL || *s == NUL || (use_string && VIM_ISDIGIT(*s)))
11860 	EMSG2(_(e_invarg2), s);
11861     /* Don't check an autoload name for existence here. */
11862     else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL
11863 						       && !function_exists(s))
11864 	EMSG2(_("E700: Unknown function: %s"), s);
11865     else
11866     {
11867 	int	dict_idx = 0;
11868 	int	arg_idx = 0;
11869 	list_T	*list = NULL;
11870 
11871 	if (STRNCMP(s, "s:", 2) == 0 || STRNCMP(s, "<SID>", 5) == 0)
11872 	{
11873 	    char	sid_buf[25];
11874 	    int		off = *s == 's' ? 2 : 5;
11875 
11876 	    /* Expand s: and <SID> into <SNR>nr_, so that the function can
11877 	     * also be called from another script. Using trans_function_name()
11878 	     * would also work, but some plugins depend on the name being
11879 	     * printable text. */
11880 	    sprintf(sid_buf, "<SNR>%ld_", (long)current_SID);
11881 	    name = alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1));
11882 	    if (name != NULL)
11883 	    {
11884 		STRCPY(name, sid_buf);
11885 		STRCAT(name, s + off);
11886 	    }
11887 	}
11888 	else
11889 	    name = vim_strsave(s);
11890 
11891 	if (argvars[1].v_type != VAR_UNKNOWN)
11892 	{
11893 	    if (argvars[2].v_type != VAR_UNKNOWN)
11894 	    {
11895 		/* function(name, [args], dict) */
11896 		arg_idx = 1;
11897 		dict_idx = 2;
11898 	    }
11899 	    else if (argvars[1].v_type == VAR_DICT)
11900 		/* function(name, dict) */
11901 		dict_idx = 1;
11902 	    else
11903 		/* function(name, [args]) */
11904 		arg_idx = 1;
11905 	    if (dict_idx > 0)
11906 	    {
11907 		if (argvars[dict_idx].v_type != VAR_DICT)
11908 		{
11909 		    EMSG(_("E922: expected a dict"));
11910 		    vim_free(name);
11911 		    return;
11912 		}
11913 		if (argvars[dict_idx].vval.v_dict == NULL)
11914 		    dict_idx = 0;
11915 	    }
11916 	    if (arg_idx > 0)
11917 	    {
11918 		if (argvars[arg_idx].v_type != VAR_LIST)
11919 		{
11920 		    EMSG(_("E923: Second argument of function() must be a list or a dict"));
11921 		    vim_free(name);
11922 		    return;
11923 		}
11924 		list = argvars[arg_idx].vval.v_list;
11925 		if (list == NULL || list->lv_len == 0)
11926 		    arg_idx = 0;
11927 	    }
11928 	}
11929 	if (dict_idx > 0 || arg_idx > 0 || arg_pt != NULL)
11930 	{
11931 	    partial_T	*pt = (partial_T *)alloc_clear(sizeof(partial_T));
11932 
11933 	    /* result is a VAR_PARTIAL */
11934 	    if (pt == NULL)
11935 		vim_free(name);
11936 	    else
11937 	    {
11938 		if (arg_idx > 0 || (arg_pt != NULL && arg_pt->pt_argc > 0))
11939 		{
11940 		    listitem_T	*li;
11941 		    int		i = 0;
11942 		    int		arg_len = 0;
11943 		    int		lv_len = 0;
11944 
11945 		    if (arg_pt != NULL)
11946 			arg_len = arg_pt->pt_argc;
11947 		    if (list != NULL)
11948 			lv_len = list->lv_len;
11949 		    pt->pt_argc = arg_len + lv_len;
11950 		    pt->pt_argv = (typval_T *)alloc(
11951 					      sizeof(typval_T) * pt->pt_argc);
11952 		    if (pt->pt_argv == NULL)
11953 		    {
11954 			vim_free(pt);
11955 			vim_free(name);
11956 			return;
11957 		    }
11958 		    else
11959 		    {
11960 			for (i = 0; i < arg_len; i++)
11961 			    copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]);
11962 			if (lv_len > 0)
11963 			    for (li = list->lv_first; li != NULL;
11964 							     li = li->li_next)
11965 				copy_tv(&li->li_tv, &pt->pt_argv[i++]);
11966 		    }
11967 		}
11968 
11969 		/* For "function(dict.func, [], dict)" and "func" is a partial
11970 		 * use "dict".  That is backwards compatible. */
11971 		if (dict_idx > 0)
11972 		{
11973 		    pt->pt_dict = argvars[dict_idx].vval.v_dict;
11974 		    ++pt->pt_dict->dv_refcount;
11975 		}
11976 		else if (arg_pt != NULL)
11977 		{
11978 		    pt->pt_dict = arg_pt->pt_dict;
11979 		    if (pt->pt_dict != NULL)
11980 			++pt->pt_dict->dv_refcount;
11981 		}
11982 
11983 		pt->pt_refcount = 1;
11984 		pt->pt_name = name;
11985 		func_ref(pt->pt_name);
11986 	    }
11987 	    rettv->v_type = VAR_PARTIAL;
11988 	    rettv->vval.v_partial = pt;
11989 	}
11990 	else
11991 	{
11992 	    /* result is a VAR_FUNC */
11993 	    rettv->v_type = VAR_FUNC;
11994 	    rettv->vval.v_string = name;
11995 	    func_ref(name);
11996 	}
11997     }
11998 }
11999 
12000     static void
12001 partial_free(partial_T *pt)
12002 {
12003     int i;
12004 
12005     for (i = 0; i < pt->pt_argc; ++i)
12006 	clear_tv(&pt->pt_argv[i]);
12007     vim_free(pt->pt_argv);
12008     func_unref(pt->pt_name);
12009     vim_free(pt->pt_name);
12010     vim_free(pt);
12011 }
12012 
12013 /*
12014  * Unreference a closure: decrement the reference count and free it when it
12015  * becomes zero.
12016  */
12017     void
12018 partial_unref(partial_T *pt)
12019 {
12020     if (pt != NULL && --pt->pt_refcount <= 0)
12021 	partial_free(pt);
12022 }
12023 
12024 /*
12025  * "garbagecollect()" function
12026  */
12027     static void
12028 f_garbagecollect(typval_T *argvars, typval_T *rettv UNUSED)
12029 {
12030     /* This is postponed until we are back at the toplevel, because we may be
12031      * using Lists and Dicts internally.  E.g.: ":echo [garbagecollect()]". */
12032     want_garbage_collect = TRUE;
12033 
12034     if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1)
12035 	garbage_collect_at_exit = TRUE;
12036 }
12037 
12038 /*
12039  * "get()" function
12040  */
12041     static void
12042 f_get(typval_T *argvars, typval_T *rettv)
12043 {
12044     listitem_T	*li;
12045     list_T	*l;
12046     dictitem_T	*di;
12047     dict_T	*d;
12048     typval_T	*tv = NULL;
12049 
12050     if (argvars[0].v_type == VAR_LIST)
12051     {
12052 	if ((l = argvars[0].vval.v_list) != NULL)
12053 	{
12054 	    int		error = FALSE;
12055 
12056 	    li = list_find(l, get_tv_number_chk(&argvars[1], &error));
12057 	    if (!error && li != NULL)
12058 		tv = &li->li_tv;
12059 	}
12060     }
12061     else if (argvars[0].v_type == VAR_DICT)
12062     {
12063 	if ((d = argvars[0].vval.v_dict) != NULL)
12064 	{
12065 	    di = dict_find(d, get_tv_string(&argvars[1]), -1);
12066 	    if (di != NULL)
12067 		tv = &di->di_tv;
12068 	}
12069     }
12070     else
12071 	EMSG2(_(e_listdictarg), "get()");
12072 
12073     if (tv == NULL)
12074     {
12075 	if (argvars[2].v_type != VAR_UNKNOWN)
12076 	    copy_tv(&argvars[2], rettv);
12077     }
12078     else
12079 	copy_tv(tv, rettv);
12080 }
12081 
12082 static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv);
12083 
12084 /*
12085  * Get line or list of lines from buffer "buf" into "rettv".
12086  * Return a range (from start to end) of lines in rettv from the specified
12087  * buffer.
12088  * If 'retlist' is TRUE, then the lines are returned as a Vim List.
12089  */
12090     static void
12091 get_buffer_lines(
12092     buf_T	*buf,
12093     linenr_T	start,
12094     linenr_T	end,
12095     int		retlist,
12096     typval_T	*rettv)
12097 {
12098     char_u	*p;
12099 
12100     rettv->v_type = VAR_STRING;
12101     rettv->vval.v_string = NULL;
12102     if (retlist && rettv_list_alloc(rettv) == FAIL)
12103 	return;
12104 
12105     if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0)
12106 	return;
12107 
12108     if (!retlist)
12109     {
12110 	if (start >= 1 && start <= buf->b_ml.ml_line_count)
12111 	    p = ml_get_buf(buf, start, FALSE);
12112 	else
12113 	    p = (char_u *)"";
12114 	rettv->vval.v_string = vim_strsave(p);
12115     }
12116     else
12117     {
12118 	if (end < start)
12119 	    return;
12120 
12121 	if (start < 1)
12122 	    start = 1;
12123 	if (end > buf->b_ml.ml_line_count)
12124 	    end = buf->b_ml.ml_line_count;
12125 	while (start <= end)
12126 	    if (list_append_string(rettv->vval.v_list,
12127 				 ml_get_buf(buf, start++, FALSE), -1) == FAIL)
12128 		break;
12129     }
12130 }
12131 
12132 /*
12133  * "getbufline()" function
12134  */
12135     static void
12136 f_getbufline(typval_T *argvars, typval_T *rettv)
12137 {
12138     linenr_T	lnum;
12139     linenr_T	end;
12140     buf_T	*buf;
12141 
12142     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
12143     ++emsg_off;
12144     buf = get_buf_tv(&argvars[0], FALSE);
12145     --emsg_off;
12146 
12147     lnum = get_tv_lnum_buf(&argvars[1], buf);
12148     if (argvars[2].v_type == VAR_UNKNOWN)
12149 	end = lnum;
12150     else
12151 	end = get_tv_lnum_buf(&argvars[2], buf);
12152 
12153     get_buffer_lines(buf, lnum, end, TRUE, rettv);
12154 }
12155 
12156 /*
12157  * "getbufvar()" function
12158  */
12159     static void
12160 f_getbufvar(typval_T *argvars, typval_T *rettv)
12161 {
12162     buf_T	*buf;
12163     buf_T	*save_curbuf;
12164     char_u	*varname;
12165     dictitem_T	*v;
12166     int		done = FALSE;
12167 
12168     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
12169     varname = get_tv_string_chk(&argvars[1]);
12170     ++emsg_off;
12171     buf = get_buf_tv(&argvars[0], FALSE);
12172 
12173     rettv->v_type = VAR_STRING;
12174     rettv->vval.v_string = NULL;
12175 
12176     if (buf != NULL && varname != NULL)
12177     {
12178 	/* set curbuf to be our buf, temporarily */
12179 	save_curbuf = curbuf;
12180 	curbuf = buf;
12181 
12182 	if (*varname == '&')	/* buffer-local-option */
12183 	{
12184 	    if (get_option_tv(&varname, rettv, TRUE) == OK)
12185 		done = TRUE;
12186 	}
12187 	else if (STRCMP(varname, "changedtick") == 0)
12188 	{
12189 	    rettv->v_type = VAR_NUMBER;
12190 	    rettv->vval.v_number = curbuf->b_changedtick;
12191 	    done = TRUE;
12192 	}
12193 	else
12194 	{
12195 	    /* Look up the variable. */
12196 	    /* Let getbufvar({nr}, "") return the "b:" dictionary. */
12197 	    v = find_var_in_ht(&curbuf->b_vars->dv_hashtab,
12198 							 'b', varname, FALSE);
12199 	    if (v != NULL)
12200 	    {
12201 		copy_tv(&v->di_tv, rettv);
12202 		done = TRUE;
12203 	    }
12204 	}
12205 
12206 	/* restore previous notion of curbuf */
12207 	curbuf = save_curbuf;
12208     }
12209 
12210     if (!done && argvars[2].v_type != VAR_UNKNOWN)
12211 	/* use the default value */
12212 	copy_tv(&argvars[2], rettv);
12213 
12214     --emsg_off;
12215 }
12216 
12217 /*
12218  * "getchar()" function
12219  */
12220     static void
12221 f_getchar(typval_T *argvars, typval_T *rettv)
12222 {
12223     varnumber_T		n;
12224     int			error = FALSE;
12225 
12226     /* Position the cursor.  Needed after a message that ends in a space. */
12227     windgoto(msg_row, msg_col);
12228 
12229     ++no_mapping;
12230     ++allow_keys;
12231     for (;;)
12232     {
12233 	if (argvars[0].v_type == VAR_UNKNOWN)
12234 	    /* getchar(): blocking wait. */
12235 	    n = safe_vgetc();
12236 	else if (get_tv_number_chk(&argvars[0], &error) == 1)
12237 	    /* getchar(1): only check if char avail */
12238 	    n = vpeekc_any();
12239 	else if (error || vpeekc_any() == NUL)
12240 	    /* illegal argument or getchar(0) and no char avail: return zero */
12241 	    n = 0;
12242 	else
12243 	    /* getchar(0) and char avail: return char */
12244 	    n = safe_vgetc();
12245 
12246 	if (n == K_IGNORE)
12247 	    continue;
12248 	break;
12249     }
12250     --no_mapping;
12251     --allow_keys;
12252 
12253     vimvars[VV_MOUSE_WIN].vv_nr = 0;
12254     vimvars[VV_MOUSE_LNUM].vv_nr = 0;
12255     vimvars[VV_MOUSE_COL].vv_nr = 0;
12256 
12257     rettv->vval.v_number = n;
12258     if (IS_SPECIAL(n) || mod_mask != 0)
12259     {
12260 	char_u		temp[10];   /* modifier: 3, mbyte-char: 6, NUL: 1 */
12261 	int		i = 0;
12262 
12263 	/* Turn a special key into three bytes, plus modifier. */
12264 	if (mod_mask != 0)
12265 	{
12266 	    temp[i++] = K_SPECIAL;
12267 	    temp[i++] = KS_MODIFIER;
12268 	    temp[i++] = mod_mask;
12269 	}
12270 	if (IS_SPECIAL(n))
12271 	{
12272 	    temp[i++] = K_SPECIAL;
12273 	    temp[i++] = K_SECOND(n);
12274 	    temp[i++] = K_THIRD(n);
12275 	}
12276 #ifdef FEAT_MBYTE
12277 	else if (has_mbyte)
12278 	    i += (*mb_char2bytes)(n, temp + i);
12279 #endif
12280 	else
12281 	    temp[i++] = n;
12282 	temp[i++] = NUL;
12283 	rettv->v_type = VAR_STRING;
12284 	rettv->vval.v_string = vim_strsave(temp);
12285 
12286 #ifdef FEAT_MOUSE
12287 	if (is_mouse_key(n))
12288 	{
12289 	    int		row = mouse_row;
12290 	    int		col = mouse_col;
12291 	    win_T	*win;
12292 	    linenr_T	lnum;
12293 # ifdef FEAT_WINDOWS
12294 	    win_T	*wp;
12295 # endif
12296 	    int		winnr = 1;
12297 
12298 	    if (row >= 0 && col >= 0)
12299 	    {
12300 		/* Find the window at the mouse coordinates and compute the
12301 		 * text position. */
12302 		win = mouse_find_win(&row, &col);
12303 		(void)mouse_comp_pos(win, &row, &col, &lnum);
12304 # ifdef FEAT_WINDOWS
12305 		for (wp = firstwin; wp != win; wp = wp->w_next)
12306 		    ++winnr;
12307 # endif
12308 		vimvars[VV_MOUSE_WIN].vv_nr = winnr;
12309 		vimvars[VV_MOUSE_LNUM].vv_nr = lnum;
12310 		vimvars[VV_MOUSE_COL].vv_nr = col + 1;
12311 	    }
12312 	}
12313 #endif
12314     }
12315 }
12316 
12317 /*
12318  * "getcharmod()" function
12319  */
12320     static void
12321 f_getcharmod(typval_T *argvars UNUSED, typval_T *rettv)
12322 {
12323     rettv->vval.v_number = mod_mask;
12324 }
12325 
12326 /*
12327  * "getcharsearch()" function
12328  */
12329     static void
12330 f_getcharsearch(typval_T *argvars UNUSED, typval_T *rettv)
12331 {
12332     if (rettv_dict_alloc(rettv) != FAIL)
12333     {
12334 	dict_T *dict = rettv->vval.v_dict;
12335 
12336 	dict_add_nr_str(dict, "char", 0L, last_csearch());
12337 	dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL);
12338 	dict_add_nr_str(dict, "until", last_csearch_until(), NULL);
12339     }
12340 }
12341 
12342 /*
12343  * "getcmdline()" function
12344  */
12345     static void
12346 f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv)
12347 {
12348     rettv->v_type = VAR_STRING;
12349     rettv->vval.v_string = get_cmdline_str();
12350 }
12351 
12352 /*
12353  * "getcmdpos()" function
12354  */
12355     static void
12356 f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv)
12357 {
12358     rettv->vval.v_number = get_cmdline_pos() + 1;
12359 }
12360 
12361 /*
12362  * "getcmdtype()" function
12363  */
12364     static void
12365 f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv)
12366 {
12367     rettv->v_type = VAR_STRING;
12368     rettv->vval.v_string = alloc(2);
12369     if (rettv->vval.v_string != NULL)
12370     {
12371 	rettv->vval.v_string[0] = get_cmdline_type();
12372 	rettv->vval.v_string[1] = NUL;
12373     }
12374 }
12375 
12376 /*
12377  * "getcmdwintype()" function
12378  */
12379     static void
12380 f_getcmdwintype(typval_T *argvars UNUSED, typval_T *rettv)
12381 {
12382     rettv->v_type = VAR_STRING;
12383     rettv->vval.v_string = NULL;
12384 #ifdef FEAT_CMDWIN
12385     rettv->vval.v_string = alloc(2);
12386     if (rettv->vval.v_string != NULL)
12387     {
12388 	rettv->vval.v_string[0] = cmdwin_type;
12389 	rettv->vval.v_string[1] = NUL;
12390     }
12391 #endif
12392 }
12393 
12394 /*
12395  * "getcwd()" function
12396  */
12397     static void
12398 f_getcwd(typval_T *argvars, typval_T *rettv)
12399 {
12400     win_T	*wp = NULL;
12401     char_u	*cwd;
12402 
12403     rettv->v_type = VAR_STRING;
12404     rettv->vval.v_string = NULL;
12405 
12406     wp = find_tabwin(&argvars[0], &argvars[1]);
12407     if (wp != NULL)
12408     {
12409 	if (wp->w_localdir != NULL)
12410 	    rettv->vval.v_string = vim_strsave(wp->w_localdir);
12411 	else if(globaldir != NULL)
12412 	    rettv->vval.v_string = vim_strsave(globaldir);
12413 	else
12414 	{
12415 	    cwd = alloc(MAXPATHL);
12416 	    if (cwd != NULL)
12417 	    {
12418 		if (mch_dirname(cwd, MAXPATHL) != FAIL)
12419 		    rettv->vval.v_string = vim_strsave(cwd);
12420 		vim_free(cwd);
12421 	    }
12422 	}
12423 #ifdef BACKSLASH_IN_FILENAME
12424 	if (rettv->vval.v_string != NULL)
12425 	    slash_adjust(rettv->vval.v_string);
12426 #endif
12427     }
12428 }
12429 
12430 /*
12431  * "getfontname()" function
12432  */
12433     static void
12434 f_getfontname(typval_T *argvars UNUSED, typval_T *rettv)
12435 {
12436     rettv->v_type = VAR_STRING;
12437     rettv->vval.v_string = NULL;
12438 #ifdef FEAT_GUI
12439     if (gui.in_use)
12440     {
12441 	GuiFont font;
12442 	char_u	*name = NULL;
12443 
12444 	if (argvars[0].v_type == VAR_UNKNOWN)
12445 	{
12446 	    /* Get the "Normal" font.  Either the name saved by
12447 	     * hl_set_font_name() or from the font ID. */
12448 	    font = gui.norm_font;
12449 	    name = hl_get_font_name();
12450 	}
12451 	else
12452 	{
12453 	    name = get_tv_string(&argvars[0]);
12454 	    if (STRCMP(name, "*") == 0)	    /* don't use font dialog */
12455 		return;
12456 	    font = gui_mch_get_font(name, FALSE);
12457 	    if (font == NOFONT)
12458 		return;	    /* Invalid font name, return empty string. */
12459 	}
12460 	rettv->vval.v_string = gui_mch_get_fontname(font, name);
12461 	if (argvars[0].v_type != VAR_UNKNOWN)
12462 	    gui_mch_free_font(font);
12463     }
12464 #endif
12465 }
12466 
12467 /*
12468  * "getfperm({fname})" function
12469  */
12470     static void
12471 f_getfperm(typval_T *argvars, typval_T *rettv)
12472 {
12473     char_u	*fname;
12474     struct stat st;
12475     char_u	*perm = NULL;
12476     char_u	flags[] = "rwx";
12477     int		i;
12478 
12479     fname = get_tv_string(&argvars[0]);
12480 
12481     rettv->v_type = VAR_STRING;
12482     if (mch_stat((char *)fname, &st) >= 0)
12483     {
12484 	perm = vim_strsave((char_u *)"---------");
12485 	if (perm != NULL)
12486 	{
12487 	    for (i = 0; i < 9; i++)
12488 	    {
12489 		if (st.st_mode & (1 << (8 - i)))
12490 		    perm[i] = flags[i % 3];
12491 	    }
12492 	}
12493     }
12494     rettv->vval.v_string = perm;
12495 }
12496 
12497 /*
12498  * "getfsize({fname})" function
12499  */
12500     static void
12501 f_getfsize(typval_T *argvars, typval_T *rettv)
12502 {
12503     char_u	*fname;
12504     struct stat	st;
12505 
12506     fname = get_tv_string(&argvars[0]);
12507 
12508     rettv->v_type = VAR_NUMBER;
12509 
12510     if (mch_stat((char *)fname, &st) >= 0)
12511     {
12512 	if (mch_isdir(fname))
12513 	    rettv->vval.v_number = 0;
12514 	else
12515 	{
12516 	    rettv->vval.v_number = (varnumber_T)st.st_size;
12517 
12518 	    /* non-perfect check for overflow */
12519 	    if ((off_t)rettv->vval.v_number != (off_t)st.st_size)
12520 		rettv->vval.v_number = -2;
12521 	}
12522     }
12523     else
12524 	  rettv->vval.v_number = -1;
12525 }
12526 
12527 /*
12528  * "getftime({fname})" function
12529  */
12530     static void
12531 f_getftime(typval_T *argvars, typval_T *rettv)
12532 {
12533     char_u	*fname;
12534     struct stat	st;
12535 
12536     fname = get_tv_string(&argvars[0]);
12537 
12538     if (mch_stat((char *)fname, &st) >= 0)
12539 	rettv->vval.v_number = (varnumber_T)st.st_mtime;
12540     else
12541 	rettv->vval.v_number = -1;
12542 }
12543 
12544 /*
12545  * "getftype({fname})" function
12546  */
12547     static void
12548 f_getftype(typval_T *argvars, typval_T *rettv)
12549 {
12550     char_u	*fname;
12551     struct stat st;
12552     char_u	*type = NULL;
12553     char	*t;
12554 
12555     fname = get_tv_string(&argvars[0]);
12556 
12557     rettv->v_type = VAR_STRING;
12558     if (mch_lstat((char *)fname, &st) >= 0)
12559     {
12560 #ifdef S_ISREG
12561 	if (S_ISREG(st.st_mode))
12562 	    t = "file";
12563 	else if (S_ISDIR(st.st_mode))
12564 	    t = "dir";
12565 # ifdef S_ISLNK
12566 	else if (S_ISLNK(st.st_mode))
12567 	    t = "link";
12568 # endif
12569 # ifdef S_ISBLK
12570 	else if (S_ISBLK(st.st_mode))
12571 	    t = "bdev";
12572 # endif
12573 # ifdef S_ISCHR
12574 	else if (S_ISCHR(st.st_mode))
12575 	    t = "cdev";
12576 # endif
12577 # ifdef S_ISFIFO
12578 	else if (S_ISFIFO(st.st_mode))
12579 	    t = "fifo";
12580 # endif
12581 # ifdef S_ISSOCK
12582 	else if (S_ISSOCK(st.st_mode))
12583 	    t = "fifo";
12584 # endif
12585 	else
12586 	    t = "other";
12587 #else
12588 # ifdef S_IFMT
12589 	switch (st.st_mode & S_IFMT)
12590 	{
12591 	    case S_IFREG: t = "file"; break;
12592 	    case S_IFDIR: t = "dir"; break;
12593 #  ifdef S_IFLNK
12594 	    case S_IFLNK: t = "link"; break;
12595 #  endif
12596 #  ifdef S_IFBLK
12597 	    case S_IFBLK: t = "bdev"; break;
12598 #  endif
12599 #  ifdef S_IFCHR
12600 	    case S_IFCHR: t = "cdev"; break;
12601 #  endif
12602 #  ifdef S_IFIFO
12603 	    case S_IFIFO: t = "fifo"; break;
12604 #  endif
12605 #  ifdef S_IFSOCK
12606 	    case S_IFSOCK: t = "socket"; break;
12607 #  endif
12608 	    default: t = "other";
12609 	}
12610 # else
12611 	if (mch_isdir(fname))
12612 	    t = "dir";
12613 	else
12614 	    t = "file";
12615 # endif
12616 #endif
12617 	type = vim_strsave((char_u *)t);
12618     }
12619     rettv->vval.v_string = type;
12620 }
12621 
12622 /*
12623  * "getline(lnum, [end])" function
12624  */
12625     static void
12626 f_getline(typval_T *argvars, typval_T *rettv)
12627 {
12628     linenr_T	lnum;
12629     linenr_T	end;
12630     int		retlist;
12631 
12632     lnum = get_tv_lnum(argvars);
12633     if (argvars[1].v_type == VAR_UNKNOWN)
12634     {
12635 	end = 0;
12636 	retlist = FALSE;
12637     }
12638     else
12639     {
12640 	end = get_tv_lnum(&argvars[1]);
12641 	retlist = TRUE;
12642     }
12643 
12644     get_buffer_lines(curbuf, lnum, end, retlist, rettv);
12645 }
12646 
12647 /*
12648  * "getmatches()" function
12649  */
12650     static void
12651 f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
12652 {
12653 #ifdef FEAT_SEARCH_EXTRA
12654     dict_T	*dict;
12655     matchitem_T	*cur = curwin->w_match_head;
12656     int		i;
12657 
12658     if (rettv_list_alloc(rettv) == OK)
12659     {
12660 	while (cur != NULL)
12661 	{
12662 	    dict = dict_alloc();
12663 	    if (dict == NULL)
12664 		return;
12665 	    if (cur->match.regprog == NULL)
12666 	    {
12667 		/* match added with matchaddpos() */
12668 		for (i = 0; i < MAXPOSMATCH; ++i)
12669 		{
12670 		    llpos_T	*llpos;
12671 		    char	buf[6];
12672 		    list_T	*l;
12673 
12674 		    llpos = &cur->pos.pos[i];
12675 		    if (llpos->lnum == 0)
12676 			break;
12677 		    l = list_alloc();
12678 		    if (l == NULL)
12679 			break;
12680 		    list_append_number(l, (varnumber_T)llpos->lnum);
12681 		    if (llpos->col > 0)
12682 		    {
12683 			list_append_number(l, (varnumber_T)llpos->col);
12684 			list_append_number(l, (varnumber_T)llpos->len);
12685 		    }
12686 		    sprintf(buf, "pos%d", i + 1);
12687 		    dict_add_list(dict, buf, l);
12688 		}
12689 	    }
12690 	    else
12691 	    {
12692 		dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
12693 	    }
12694 	    dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
12695 	    dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
12696 	    dict_add_nr_str(dict, "id", (long)cur->id, NULL);
12697 # ifdef FEAT_CONCEAL
12698 	    if (cur->conceal_char)
12699 	    {
12700 		char_u buf[MB_MAXBYTES + 1];
12701 
12702 		buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
12703 		dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf);
12704 	    }
12705 # endif
12706 	    list_append_dict(rettv->vval.v_list, dict);
12707 	    cur = cur->next;
12708 	}
12709     }
12710 #endif
12711 }
12712 
12713 /*
12714  * "getpid()" function
12715  */
12716     static void
12717 f_getpid(typval_T *argvars UNUSED, typval_T *rettv)
12718 {
12719     rettv->vval.v_number = mch_get_pid();
12720 }
12721 
12722 static void getpos_both(typval_T *argvars, typval_T *rettv, int getcurpos);
12723 
12724 /*
12725  * "getcurpos()" function
12726  */
12727     static void
12728 f_getcurpos(typval_T *argvars, typval_T *rettv)
12729 {
12730     getpos_both(argvars, rettv, TRUE);
12731 }
12732 
12733 /*
12734  * "getpos(string)" function
12735  */
12736     static void
12737 f_getpos(typval_T *argvars, typval_T *rettv)
12738 {
12739     getpos_both(argvars, rettv, FALSE);
12740 }
12741 
12742     static void
12743 getpos_both(
12744     typval_T	*argvars,
12745     typval_T	*rettv,
12746     int		getcurpos)
12747 {
12748     pos_T	*fp;
12749     list_T	*l;
12750     int		fnum = -1;
12751 
12752     if (rettv_list_alloc(rettv) == OK)
12753     {
12754 	l = rettv->vval.v_list;
12755 	if (getcurpos)
12756 	    fp = &curwin->w_cursor;
12757 	else
12758 	    fp = var2fpos(&argvars[0], TRUE, &fnum);
12759 	if (fnum != -1)
12760 	    list_append_number(l, (varnumber_T)fnum);
12761 	else
12762 	    list_append_number(l, (varnumber_T)0);
12763 	list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum
12764 							    : (varnumber_T)0);
12765 	list_append_number(l, (fp != NULL)
12766 		     ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
12767 							    : (varnumber_T)0);
12768 	list_append_number(l,
12769 #ifdef FEAT_VIRTUALEDIT
12770 				(fp != NULL) ? (varnumber_T)fp->coladd :
12771 #endif
12772 							      (varnumber_T)0);
12773 	if (getcurpos)
12774 	{
12775 	    update_curswant();
12776 	    list_append_number(l, curwin->w_curswant == MAXCOL ?
12777 		    (varnumber_T)MAXCOL : (varnumber_T)curwin->w_curswant + 1);
12778 	}
12779     }
12780     else
12781 	rettv->vval.v_number = FALSE;
12782 }
12783 
12784 /*
12785  * "getqflist()" and "getloclist()" functions
12786  */
12787     static void
12788 f_getqflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
12789 {
12790 #ifdef FEAT_QUICKFIX
12791     win_T	*wp;
12792 #endif
12793 
12794 #ifdef FEAT_QUICKFIX
12795     if (rettv_list_alloc(rettv) == OK)
12796     {
12797 	wp = NULL;
12798 	if (argvars[0].v_type != VAR_UNKNOWN)	/* getloclist() */
12799 	{
12800 	    wp = find_win_by_nr(&argvars[0], NULL);
12801 	    if (wp == NULL)
12802 		return;
12803 	}
12804 
12805 	(void)get_errorlist(wp, rettv->vval.v_list);
12806     }
12807 #endif
12808 }
12809 
12810 /*
12811  * "getreg()" function
12812  */
12813     static void
12814 f_getreg(typval_T *argvars, typval_T *rettv)
12815 {
12816     char_u	*strregname;
12817     int		regname;
12818     int		arg2 = FALSE;
12819     int		return_list = FALSE;
12820     int		error = FALSE;
12821 
12822     if (argvars[0].v_type != VAR_UNKNOWN)
12823     {
12824 	strregname = get_tv_string_chk(&argvars[0]);
12825 	error = strregname == NULL;
12826 	if (argvars[1].v_type != VAR_UNKNOWN)
12827 	{
12828 	    arg2 = get_tv_number_chk(&argvars[1], &error);
12829 	    if (!error && argvars[2].v_type != VAR_UNKNOWN)
12830 		return_list = get_tv_number_chk(&argvars[2], &error);
12831 	}
12832     }
12833     else
12834 	strregname = vimvars[VV_REG].vv_str;
12835 
12836     if (error)
12837 	return;
12838 
12839     regname = (strregname == NULL ? '"' : *strregname);
12840     if (regname == 0)
12841 	regname = '"';
12842 
12843     if (return_list)
12844     {
12845 	rettv->v_type = VAR_LIST;
12846 	rettv->vval.v_list = (list_T *)get_reg_contents(regname,
12847 				      (arg2 ? GREG_EXPR_SRC : 0) | GREG_LIST);
12848 	if (rettv->vval.v_list != NULL)
12849 	    ++rettv->vval.v_list->lv_refcount;
12850     }
12851     else
12852     {
12853 	rettv->v_type = VAR_STRING;
12854 	rettv->vval.v_string = get_reg_contents(regname,
12855 						    arg2 ? GREG_EXPR_SRC : 0);
12856     }
12857 }
12858 
12859 /*
12860  * "getregtype()" function
12861  */
12862     static void
12863 f_getregtype(typval_T *argvars, typval_T *rettv)
12864 {
12865     char_u	*strregname;
12866     int		regname;
12867     char_u	buf[NUMBUFLEN + 2];
12868     long	reglen = 0;
12869 
12870     if (argvars[0].v_type != VAR_UNKNOWN)
12871     {
12872 	strregname = get_tv_string_chk(&argvars[0]);
12873 	if (strregname == NULL)	    /* type error; errmsg already given */
12874 	{
12875 	    rettv->v_type = VAR_STRING;
12876 	    rettv->vval.v_string = NULL;
12877 	    return;
12878 	}
12879     }
12880     else
12881 	/* Default to v:register */
12882 	strregname = vimvars[VV_REG].vv_str;
12883 
12884     regname = (strregname == NULL ? '"' : *strregname);
12885     if (regname == 0)
12886 	regname = '"';
12887 
12888     buf[0] = NUL;
12889     buf[1] = NUL;
12890     switch (get_reg_type(regname, &reglen))
12891     {
12892 	case MLINE: buf[0] = 'V'; break;
12893 	case MCHAR: buf[0] = 'v'; break;
12894 	case MBLOCK:
12895 		buf[0] = Ctrl_V;
12896 		sprintf((char *)buf + 1, "%ld", reglen + 1);
12897 		break;
12898     }
12899     rettv->v_type = VAR_STRING;
12900     rettv->vval.v_string = vim_strsave(buf);
12901 }
12902 
12903 /*
12904  * "gettabvar()" function
12905  */
12906     static void
12907 f_gettabvar(typval_T *argvars, typval_T *rettv)
12908 {
12909     win_T	*oldcurwin;
12910     tabpage_T	*tp, *oldtabpage;
12911     dictitem_T	*v;
12912     char_u	*varname;
12913     int		done = FALSE;
12914 
12915     rettv->v_type = VAR_STRING;
12916     rettv->vval.v_string = NULL;
12917 
12918     varname = get_tv_string_chk(&argvars[1]);
12919     tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
12920     if (tp != NULL && varname != NULL)
12921     {
12922 	/* Set tp to be our tabpage, temporarily.  Also set the window to the
12923 	 * first window in the tabpage, otherwise the window is not valid. */
12924 	if (switch_win(&oldcurwin, &oldtabpage,
12925 		    tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin, tp, TRUE)
12926 									== OK)
12927 	{
12928 	    /* look up the variable */
12929 	    /* Let gettabvar({nr}, "") return the "t:" dictionary. */
12930 	    v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE);
12931 	    if (v != NULL)
12932 	    {
12933 		copy_tv(&v->di_tv, rettv);
12934 		done = TRUE;
12935 	    }
12936 	}
12937 
12938 	/* restore previous notion of curwin */
12939 	restore_win(oldcurwin, oldtabpage, TRUE);
12940     }
12941 
12942     if (!done && argvars[2].v_type != VAR_UNKNOWN)
12943 	copy_tv(&argvars[2], rettv);
12944 }
12945 
12946 /*
12947  * "gettabwinvar()" function
12948  */
12949     static void
12950 f_gettabwinvar(typval_T *argvars, typval_T *rettv)
12951 {
12952     getwinvar(argvars, rettv, 1);
12953 }
12954 
12955 /*
12956  * "getwinposx()" function
12957  */
12958     static void
12959 f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
12960 {
12961     rettv->vval.v_number = -1;
12962 #ifdef FEAT_GUI
12963     if (gui.in_use)
12964     {
12965 	int	    x, y;
12966 
12967 	if (gui_mch_get_winpos(&x, &y) == OK)
12968 	    rettv->vval.v_number = x;
12969     }
12970 #endif
12971 }
12972 
12973 /*
12974  * "win_findbuf()" function
12975  */
12976     static void
12977 f_win_findbuf(typval_T *argvars, typval_T *rettv)
12978 {
12979     if (rettv_list_alloc(rettv) != FAIL)
12980 	win_findbuf(argvars, rettv->vval.v_list);
12981 }
12982 
12983 /*
12984  * "win_getid()" function
12985  */
12986     static void
12987 f_win_getid(typval_T *argvars, typval_T *rettv)
12988 {
12989     rettv->vval.v_number = win_getid(argvars);
12990 }
12991 
12992 /*
12993  * "win_gotoid()" function
12994  */
12995     static void
12996 f_win_gotoid(typval_T *argvars, typval_T *rettv)
12997 {
12998     rettv->vval.v_number = win_gotoid(argvars);
12999 }
13000 
13001 /*
13002  * "win_id2tabwin()" function
13003  */
13004     static void
13005 f_win_id2tabwin(typval_T *argvars, typval_T *rettv)
13006 {
13007     if (rettv_list_alloc(rettv) != FAIL)
13008 	win_id2tabwin(argvars, rettv->vval.v_list);
13009 }
13010 
13011 /*
13012  * "win_id2win()" function
13013  */
13014     static void
13015 f_win_id2win(typval_T *argvars, typval_T *rettv)
13016 {
13017     rettv->vval.v_number = win_id2win(argvars);
13018 }
13019 
13020 /*
13021  * "getwinposy()" function
13022  */
13023     static void
13024 f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
13025 {
13026     rettv->vval.v_number = -1;
13027 #ifdef FEAT_GUI
13028     if (gui.in_use)
13029     {
13030 	int	    x, y;
13031 
13032 	if (gui_mch_get_winpos(&x, &y) == OK)
13033 	    rettv->vval.v_number = y;
13034     }
13035 #endif
13036 }
13037 
13038 /*
13039  * Find window specified by "vp" in tabpage "tp".
13040  */
13041     static win_T *
13042 find_win_by_nr(
13043     typval_T	*vp,
13044     tabpage_T	*tp UNUSED)	/* NULL for current tab page */
13045 {
13046 #ifdef FEAT_WINDOWS
13047     win_T	*wp;
13048 #endif
13049     int		nr;
13050 
13051     nr = get_tv_number_chk(vp, NULL);
13052 
13053 #ifdef FEAT_WINDOWS
13054     if (nr < 0)
13055 	return NULL;
13056     if (nr == 0)
13057 	return curwin;
13058 
13059     for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin;
13060 						  wp != NULL; wp = wp->w_next)
13061 	if (--nr <= 0)
13062 	    break;
13063     return wp;
13064 #else
13065     if (nr == 0 || nr == 1)
13066 	return curwin;
13067     return NULL;
13068 #endif
13069 }
13070 
13071 /*
13072  * Find window specified by "wvp" in tabpage "tvp".
13073  */
13074     static win_T *
13075 find_tabwin(
13076     typval_T	*wvp,	/* VAR_UNKNOWN for current window */
13077     typval_T	*tvp)	/* VAR_UNKNOWN for current tab page */
13078 {
13079     win_T	*wp = NULL;
13080     tabpage_T	*tp = NULL;
13081     long	n;
13082 
13083     if (wvp->v_type != VAR_UNKNOWN)
13084     {
13085 	if (tvp->v_type != VAR_UNKNOWN)
13086 	{
13087 	    n = get_tv_number(tvp);
13088 	    if (n >= 0)
13089 		tp = find_tabpage(n);
13090 	}
13091 	else
13092 	    tp = curtab;
13093 
13094 	if (tp != NULL)
13095 	    wp = find_win_by_nr(wvp, tp);
13096     }
13097     else
13098 	wp = curwin;
13099 
13100     return wp;
13101 }
13102 
13103 /*
13104  * "getwinvar()" function
13105  */
13106     static void
13107 f_getwinvar(typval_T *argvars, typval_T *rettv)
13108 {
13109     getwinvar(argvars, rettv, 0);
13110 }
13111 
13112 /*
13113  * getwinvar() and gettabwinvar()
13114  */
13115     static void
13116 getwinvar(
13117     typval_T	*argvars,
13118     typval_T	*rettv,
13119     int		off)	    /* 1 for gettabwinvar() */
13120 {
13121     win_T	*win;
13122     char_u	*varname;
13123     dictitem_T	*v;
13124     tabpage_T	*tp = NULL;
13125     int		done = FALSE;
13126 #ifdef FEAT_WINDOWS
13127     win_T	*oldcurwin;
13128     tabpage_T	*oldtabpage;
13129     int		need_switch_win;
13130 #endif
13131 
13132 #ifdef FEAT_WINDOWS
13133     if (off == 1)
13134 	tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
13135     else
13136 	tp = curtab;
13137 #endif
13138     win = find_win_by_nr(&argvars[off], tp);
13139     varname = get_tv_string_chk(&argvars[off + 1]);
13140     ++emsg_off;
13141 
13142     rettv->v_type = VAR_STRING;
13143     rettv->vval.v_string = NULL;
13144 
13145     if (win != NULL && varname != NULL)
13146     {
13147 #ifdef FEAT_WINDOWS
13148 	/* Set curwin to be our win, temporarily.  Also set the tabpage,
13149 	 * otherwise the window is not valid. Only do this when needed,
13150 	 * autocommands get blocked. */
13151 	need_switch_win = !(tp == curtab && win == curwin);
13152 	if (!need_switch_win
13153 		  || switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK)
13154 #endif
13155 	{
13156 	    if (*varname == '&')	/* window-local-option */
13157 	    {
13158 		if (get_option_tv(&varname, rettv, 1) == OK)
13159 		    done = TRUE;
13160 	    }
13161 	    else
13162 	    {
13163 		/* Look up the variable. */
13164 		/* Let getwinvar({nr}, "") return the "w:" dictionary. */
13165 		v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w',
13166 							      varname, FALSE);
13167 		if (v != NULL)
13168 		{
13169 		    copy_tv(&v->di_tv, rettv);
13170 		    done = TRUE;
13171 		}
13172 	    }
13173 	}
13174 
13175 #ifdef FEAT_WINDOWS
13176 	if (need_switch_win)
13177 	    /* restore previous notion of curwin */
13178 	    restore_win(oldcurwin, oldtabpage, TRUE);
13179 #endif
13180     }
13181 
13182     if (!done && argvars[off + 2].v_type != VAR_UNKNOWN)
13183 	/* use the default return value */
13184 	copy_tv(&argvars[off + 2], rettv);
13185 
13186     --emsg_off;
13187 }
13188 
13189 /*
13190  * "glob()" function
13191  */
13192     static void
13193 f_glob(typval_T *argvars, typval_T *rettv)
13194 {
13195     int		options = WILD_SILENT|WILD_USE_NL;
13196     expand_T	xpc;
13197     int		error = FALSE;
13198 
13199     /* When the optional second argument is non-zero, don't remove matches
13200      * for 'wildignore' and don't put matches for 'suffixes' at the end. */
13201     rettv->v_type = VAR_STRING;
13202     if (argvars[1].v_type != VAR_UNKNOWN)
13203     {
13204 	if (get_tv_number_chk(&argvars[1], &error))
13205 	    options |= WILD_KEEP_ALL;
13206 	if (argvars[2].v_type != VAR_UNKNOWN)
13207 	{
13208 	    if (get_tv_number_chk(&argvars[2], &error))
13209 	    {
13210 		rettv->v_type = VAR_LIST;
13211 		rettv->vval.v_list = NULL;
13212 	    }
13213 	    if (argvars[3].v_type != VAR_UNKNOWN
13214 				    && get_tv_number_chk(&argvars[3], &error))
13215 		options |= WILD_ALLLINKS;
13216 	}
13217     }
13218     if (!error)
13219     {
13220 	ExpandInit(&xpc);
13221 	xpc.xp_context = EXPAND_FILES;
13222 	if (p_wic)
13223 	    options += WILD_ICASE;
13224 	if (rettv->v_type == VAR_STRING)
13225 	    rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]),
13226 						     NULL, options, WILD_ALL);
13227 	else if (rettv_list_alloc(rettv) != FAIL)
13228 	{
13229 	  int i;
13230 
13231 	  ExpandOne(&xpc, get_tv_string(&argvars[0]),
13232 						NULL, options, WILD_ALL_KEEP);
13233 	  for (i = 0; i < xpc.xp_numfiles; i++)
13234 	      list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
13235 
13236 	  ExpandCleanup(&xpc);
13237 	}
13238     }
13239     else
13240 	rettv->vval.v_string = NULL;
13241 }
13242 
13243 /*
13244  * "globpath()" function
13245  */
13246     static void
13247 f_globpath(typval_T *argvars, typval_T *rettv)
13248 {
13249     int		flags = 0;
13250     char_u	buf1[NUMBUFLEN];
13251     char_u	*file = get_tv_string_buf_chk(&argvars[1], buf1);
13252     int		error = FALSE;
13253     garray_T	ga;
13254     int		i;
13255 
13256     /* When the optional second argument is non-zero, don't remove matches
13257     * for 'wildignore' and don't put matches for 'suffixes' at the end. */
13258     rettv->v_type = VAR_STRING;
13259     if (argvars[2].v_type != VAR_UNKNOWN)
13260     {
13261 	if (get_tv_number_chk(&argvars[2], &error))
13262 	    flags |= WILD_KEEP_ALL;
13263 	if (argvars[3].v_type != VAR_UNKNOWN)
13264 	{
13265 	    if (get_tv_number_chk(&argvars[3], &error))
13266 	    {
13267 		rettv->v_type = VAR_LIST;
13268 		rettv->vval.v_list = NULL;
13269 	    }
13270 	    if (argvars[4].v_type != VAR_UNKNOWN
13271 				    && get_tv_number_chk(&argvars[4], &error))
13272 		flags |= WILD_ALLLINKS;
13273 	}
13274     }
13275     if (file != NULL && !error)
13276     {
13277 	ga_init2(&ga, (int)sizeof(char_u *), 10);
13278 	globpath(get_tv_string(&argvars[0]), file, &ga, flags);
13279 	if (rettv->v_type == VAR_STRING)
13280 	    rettv->vval.v_string = ga_concat_strings(&ga, "\n");
13281 	else if (rettv_list_alloc(rettv) != FAIL)
13282 	    for (i = 0; i < ga.ga_len; ++i)
13283 		list_append_string(rettv->vval.v_list,
13284 					    ((char_u **)(ga.ga_data))[i], -1);
13285 	ga_clear_strings(&ga);
13286     }
13287     else
13288 	rettv->vval.v_string = NULL;
13289 }
13290 
13291 /*
13292  * "glob2regpat()" function
13293  */
13294     static void
13295 f_glob2regpat(typval_T *argvars, typval_T *rettv)
13296 {
13297     char_u	*pat = get_tv_string_chk(&argvars[0]);
13298 
13299     rettv->v_type = VAR_STRING;
13300     rettv->vval.v_string = (pat == NULL)
13301 			 ? NULL : file_pat_to_reg_pat(pat, NULL, NULL, FALSE);
13302 }
13303 
13304 /*
13305  * "has()" function
13306  */
13307     static void
13308 f_has(typval_T *argvars, typval_T *rettv)
13309 {
13310     int		i;
13311     char_u	*name;
13312     int		n = FALSE;
13313     static char	*(has_list[]) =
13314     {
13315 #ifdef AMIGA
13316 	"amiga",
13317 # ifdef FEAT_ARP
13318 	"arp",
13319 # endif
13320 #endif
13321 #ifdef __BEOS__
13322 	"beos",
13323 #endif
13324 #ifdef MACOS
13325 	"mac",
13326 #endif
13327 #if defined(MACOS_X_UNIX)
13328 	"macunix",  /* built with 'darwin' enabled */
13329 #endif
13330 #if defined(__APPLE__) && __APPLE__ == 1
13331 	"osx",	    /* built with or without 'darwin' enabled */
13332 #endif
13333 #ifdef __QNX__
13334 	"qnx",
13335 #endif
13336 #ifdef UNIX
13337 	"unix",
13338 #endif
13339 #ifdef VMS
13340 	"vms",
13341 #endif
13342 #ifdef WIN32
13343 	"win32",
13344 #endif
13345 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__))
13346 	"win32unix",
13347 #endif
13348 #if defined(WIN64) || defined(_WIN64)
13349 	"win64",
13350 #endif
13351 #ifdef EBCDIC
13352 	"ebcdic",
13353 #endif
13354 #ifndef CASE_INSENSITIVE_FILENAME
13355 	"fname_case",
13356 #endif
13357 #ifdef HAVE_ACL
13358 	"acl",
13359 #endif
13360 #ifdef FEAT_ARABIC
13361 	"arabic",
13362 #endif
13363 #ifdef FEAT_AUTOCMD
13364 	"autocmd",
13365 #endif
13366 #ifdef FEAT_BEVAL
13367 	"balloon_eval",
13368 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */
13369 	"balloon_multiline",
13370 # endif
13371 #endif
13372 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
13373 	"builtin_terms",
13374 # ifdef ALL_BUILTIN_TCAPS
13375 	"all_builtin_terms",
13376 # endif
13377 #endif
13378 #if defined(FEAT_BROWSE) && (defined(USE_FILE_CHOOSER) \
13379 	|| defined(FEAT_GUI_W32) \
13380 	|| defined(FEAT_GUI_MOTIF))
13381 	"browsefilter",
13382 #endif
13383 #ifdef FEAT_BYTEOFF
13384 	"byte_offset",
13385 #endif
13386 #ifdef FEAT_JOB_CHANNEL
13387 	"channel",
13388 #endif
13389 #ifdef FEAT_CINDENT
13390 	"cindent",
13391 #endif
13392 #ifdef FEAT_CLIENTSERVER
13393 	"clientserver",
13394 #endif
13395 #ifdef FEAT_CLIPBOARD
13396 	"clipboard",
13397 #endif
13398 #ifdef FEAT_CMDL_COMPL
13399 	"cmdline_compl",
13400 #endif
13401 #ifdef FEAT_CMDHIST
13402 	"cmdline_hist",
13403 #endif
13404 #ifdef FEAT_COMMENTS
13405 	"comments",
13406 #endif
13407 #ifdef FEAT_CONCEAL
13408 	"conceal",
13409 #endif
13410 #ifdef FEAT_CRYPT
13411 	"cryptv",
13412 	"crypt-blowfish",
13413 	"crypt-blowfish2",
13414 #endif
13415 #ifdef FEAT_CSCOPE
13416 	"cscope",
13417 #endif
13418 #ifdef FEAT_CURSORBIND
13419 	"cursorbind",
13420 #endif
13421 #ifdef CURSOR_SHAPE
13422 	"cursorshape",
13423 #endif
13424 #ifdef DEBUG
13425 	"debug",
13426 #endif
13427 #ifdef FEAT_CON_DIALOG
13428 	"dialog_con",
13429 #endif
13430 #ifdef FEAT_GUI_DIALOG
13431 	"dialog_gui",
13432 #endif
13433 #ifdef FEAT_DIFF
13434 	"diff",
13435 #endif
13436 #ifdef FEAT_DIGRAPHS
13437 	"digraphs",
13438 #endif
13439 #ifdef FEAT_DIRECTX
13440 	"directx",
13441 #endif
13442 #ifdef FEAT_DND
13443 	"dnd",
13444 #endif
13445 #ifdef FEAT_EMACS_TAGS
13446 	"emacs_tags",
13447 #endif
13448 	"eval",	    /* always present, of course! */
13449 	"ex_extra", /* graduated feature */
13450 #ifdef FEAT_SEARCH_EXTRA
13451 	"extra_search",
13452 #endif
13453 #ifdef FEAT_FKMAP
13454 	"farsi",
13455 #endif
13456 #ifdef FEAT_SEARCHPATH
13457 	"file_in_path",
13458 #endif
13459 #ifdef FEAT_FILTERPIPE
13460 	"filterpipe",
13461 #endif
13462 #ifdef FEAT_FIND_ID
13463 	"find_in_path",
13464 #endif
13465 #ifdef FEAT_FLOAT
13466 	"float",
13467 #endif
13468 #ifdef FEAT_FOLDING
13469 	"folding",
13470 #endif
13471 #ifdef FEAT_FOOTER
13472 	"footer",
13473 #endif
13474 #if !defined(USE_SYSTEM) && defined(UNIX)
13475 	"fork",
13476 #endif
13477 #ifdef FEAT_GETTEXT
13478 	"gettext",
13479 #endif
13480 #ifdef FEAT_GUI
13481 	"gui",
13482 #endif
13483 #ifdef FEAT_GUI_ATHENA
13484 # ifdef FEAT_GUI_NEXTAW
13485 	"gui_neXtaw",
13486 # else
13487 	"gui_athena",
13488 # endif
13489 #endif
13490 #ifdef FEAT_GUI_GTK
13491 	"gui_gtk",
13492 # ifdef USE_GTK3
13493 	"gui_gtk3",
13494 # else
13495 	"gui_gtk2",
13496 # endif
13497 #endif
13498 #ifdef FEAT_GUI_GNOME
13499 	"gui_gnome",
13500 #endif
13501 #ifdef FEAT_GUI_MAC
13502 	"gui_mac",
13503 #endif
13504 #ifdef FEAT_GUI_MOTIF
13505 	"gui_motif",
13506 #endif
13507 #ifdef FEAT_GUI_PHOTON
13508 	"gui_photon",
13509 #endif
13510 #ifdef FEAT_GUI_W32
13511 	"gui_win32",
13512 #endif
13513 #ifdef FEAT_HANGULIN
13514 	"hangul_input",
13515 #endif
13516 #if defined(HAVE_ICONV_H) && defined(USE_ICONV)
13517 	"iconv",
13518 #endif
13519 #ifdef FEAT_INS_EXPAND
13520 	"insert_expand",
13521 #endif
13522 #ifdef FEAT_JOB_CHANNEL
13523 	"job",
13524 #endif
13525 #ifdef FEAT_JUMPLIST
13526 	"jumplist",
13527 #endif
13528 #ifdef FEAT_KEYMAP
13529 	"keymap",
13530 #endif
13531 #ifdef FEAT_LANGMAP
13532 	"langmap",
13533 #endif
13534 #ifdef FEAT_LIBCALL
13535 	"libcall",
13536 #endif
13537 #ifdef FEAT_LINEBREAK
13538 	"linebreak",
13539 #endif
13540 #ifdef FEAT_LISP
13541 	"lispindent",
13542 #endif
13543 #ifdef FEAT_LISTCMDS
13544 	"listcmds",
13545 #endif
13546 #ifdef FEAT_LOCALMAP
13547 	"localmap",
13548 #endif
13549 #ifdef FEAT_LUA
13550 # ifndef DYNAMIC_LUA
13551 	"lua",
13552 # endif
13553 #endif
13554 #ifdef FEAT_MENU
13555 	"menu",
13556 #endif
13557 #ifdef FEAT_SESSION
13558 	"mksession",
13559 #endif
13560 #ifdef FEAT_MODIFY_FNAME
13561 	"modify_fname",
13562 #endif
13563 #ifdef FEAT_MOUSE
13564 	"mouse",
13565 #endif
13566 #ifdef FEAT_MOUSESHAPE
13567 	"mouseshape",
13568 #endif
13569 #if defined(UNIX) || defined(VMS)
13570 # ifdef FEAT_MOUSE_DEC
13571 	"mouse_dec",
13572 # endif
13573 # ifdef FEAT_MOUSE_GPM
13574 	"mouse_gpm",
13575 # endif
13576 # ifdef FEAT_MOUSE_JSB
13577 	"mouse_jsbterm",
13578 # endif
13579 # ifdef FEAT_MOUSE_NET
13580 	"mouse_netterm",
13581 # endif
13582 # ifdef FEAT_MOUSE_PTERM
13583 	"mouse_pterm",
13584 # endif
13585 # ifdef FEAT_MOUSE_SGR
13586 	"mouse_sgr",
13587 # endif
13588 # ifdef FEAT_SYSMOUSE
13589 	"mouse_sysmouse",
13590 # endif
13591 # ifdef FEAT_MOUSE_URXVT
13592 	"mouse_urxvt",
13593 # endif
13594 # ifdef FEAT_MOUSE_XTERM
13595 	"mouse_xterm",
13596 # endif
13597 #endif
13598 #ifdef FEAT_MBYTE
13599 	"multi_byte",
13600 #endif
13601 #ifdef FEAT_MBYTE_IME
13602 	"multi_byte_ime",
13603 #endif
13604 #ifdef FEAT_MULTI_LANG
13605 	"multi_lang",
13606 #endif
13607 #ifdef FEAT_MZSCHEME
13608 #ifndef DYNAMIC_MZSCHEME
13609 	"mzscheme",
13610 #endif
13611 #endif
13612 #ifdef FEAT_OLE
13613 	"ole",
13614 #endif
13615 	"packages",
13616 #ifdef FEAT_PATH_EXTRA
13617 	"path_extra",
13618 #endif
13619 #ifdef FEAT_PERL
13620 #ifndef DYNAMIC_PERL
13621 	"perl",
13622 #endif
13623 #endif
13624 #ifdef FEAT_PERSISTENT_UNDO
13625 	"persistent_undo",
13626 #endif
13627 #ifdef FEAT_PYTHON
13628 #ifndef DYNAMIC_PYTHON
13629 	"python",
13630 #endif
13631 #endif
13632 #ifdef FEAT_PYTHON3
13633 #ifndef DYNAMIC_PYTHON3
13634 	"python3",
13635 #endif
13636 #endif
13637 #ifdef FEAT_POSTSCRIPT
13638 	"postscript",
13639 #endif
13640 #ifdef FEAT_PRINTER
13641 	"printer",
13642 #endif
13643 #ifdef FEAT_PROFILE
13644 	"profile",
13645 #endif
13646 #ifdef FEAT_RELTIME
13647 	"reltime",
13648 #endif
13649 #ifdef FEAT_QUICKFIX
13650 	"quickfix",
13651 #endif
13652 #ifdef FEAT_RIGHTLEFT
13653 	"rightleft",
13654 #endif
13655 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY)
13656 	"ruby",
13657 #endif
13658 #ifdef FEAT_SCROLLBIND
13659 	"scrollbind",
13660 #endif
13661 #ifdef FEAT_CMDL_INFO
13662 	"showcmd",
13663 	"cmdline_info",
13664 #endif
13665 #ifdef FEAT_SIGNS
13666 	"signs",
13667 #endif
13668 #ifdef FEAT_SMARTINDENT
13669 	"smartindent",
13670 #endif
13671 #ifdef STARTUPTIME
13672 	"startuptime",
13673 #endif
13674 #ifdef FEAT_STL_OPT
13675 	"statusline",
13676 #endif
13677 #ifdef FEAT_SUN_WORKSHOP
13678 	"sun_workshop",
13679 #endif
13680 #ifdef FEAT_NETBEANS_INTG
13681 	"netbeans_intg",
13682 #endif
13683 #ifdef FEAT_SPELL
13684 	"spell",
13685 #endif
13686 #ifdef FEAT_SYN_HL
13687 	"syntax",
13688 #endif
13689 #if defined(USE_SYSTEM) || !defined(UNIX)
13690 	"system",
13691 #endif
13692 #ifdef FEAT_TAG_BINS
13693 	"tag_binary",
13694 #endif
13695 #ifdef FEAT_TAG_OLDSTATIC
13696 	"tag_old_static",
13697 #endif
13698 #ifdef FEAT_TAG_ANYWHITE
13699 	"tag_any_white",
13700 #endif
13701 #ifdef FEAT_TCL
13702 # ifndef DYNAMIC_TCL
13703 	"tcl",
13704 # endif
13705 #endif
13706 #ifdef TERMINFO
13707 	"terminfo",
13708 #endif
13709 #ifdef FEAT_TERMRESPONSE
13710 	"termresponse",
13711 #endif
13712 #ifdef FEAT_TEXTOBJ
13713 	"textobjects",
13714 #endif
13715 #ifdef HAVE_TGETENT
13716 	"tgetent",
13717 #endif
13718 #ifdef FEAT_TIMERS
13719 	"timers",
13720 #endif
13721 #ifdef FEAT_TITLE
13722 	"title",
13723 #endif
13724 #ifdef FEAT_TOOLBAR
13725 	"toolbar",
13726 #endif
13727 #if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
13728 	"unnamedplus",
13729 #endif
13730 #ifdef FEAT_USR_CMDS
13731 	"user-commands",    /* was accidentally included in 5.4 */
13732 	"user_commands",
13733 #endif
13734 #ifdef FEAT_VIMINFO
13735 	"viminfo",
13736 #endif
13737 #ifdef FEAT_VERTSPLIT
13738 	"vertsplit",
13739 #endif
13740 #ifdef FEAT_VIRTUALEDIT
13741 	"virtualedit",
13742 #endif
13743 	"visual",
13744 #ifdef FEAT_VISUALEXTRA
13745 	"visualextra",
13746 #endif
13747 #ifdef FEAT_VREPLACE
13748 	"vreplace",
13749 #endif
13750 #ifdef FEAT_WILDIGN
13751 	"wildignore",
13752 #endif
13753 #ifdef FEAT_WILDMENU
13754 	"wildmenu",
13755 #endif
13756 #ifdef FEAT_WINDOWS
13757 	"windows",
13758 #endif
13759 #ifdef FEAT_WAK
13760 	"winaltkeys",
13761 #endif
13762 #ifdef FEAT_WRITEBACKUP
13763 	"writebackup",
13764 #endif
13765 #ifdef FEAT_XIM
13766 	"xim",
13767 #endif
13768 #ifdef FEAT_XFONTSET
13769 	"xfontset",
13770 #endif
13771 #ifdef FEAT_XPM_W32
13772 	"xpm",
13773 	"xpm_w32",	/* for backward compatibility */
13774 #else
13775 # if defined(HAVE_XPM)
13776 	"xpm",
13777 # endif
13778 #endif
13779 #ifdef USE_XSMP
13780 	"xsmp",
13781 #endif
13782 #ifdef USE_XSMP_INTERACT
13783 	"xsmp_interact",
13784 #endif
13785 #ifdef FEAT_XCLIPBOARD
13786 	"xterm_clipboard",
13787 #endif
13788 #ifdef FEAT_XTERM_SAVE
13789 	"xterm_save",
13790 #endif
13791 #if defined(UNIX) && defined(FEAT_X11)
13792 	"X11",
13793 #endif
13794 	NULL
13795     };
13796 
13797     name = get_tv_string(&argvars[0]);
13798     for (i = 0; has_list[i] != NULL; ++i)
13799 	if (STRICMP(name, has_list[i]) == 0)
13800 	{
13801 	    n = TRUE;
13802 	    break;
13803 	}
13804 
13805     if (n == FALSE)
13806     {
13807 	if (STRNICMP(name, "patch", 5) == 0)
13808 	{
13809 	    if (name[5] == '-'
13810 		    && STRLEN(name) > 11
13811 		    && vim_isdigit(name[6])
13812 		    && vim_isdigit(name[8])
13813 		    && vim_isdigit(name[10]))
13814 	    {
13815 		int major = atoi((char *)name + 6);
13816 		int minor = atoi((char *)name + 8);
13817 
13818 		/* Expect "patch-9.9.01234". */
13819 		n = (major < VIM_VERSION_MAJOR
13820 		     || (major == VIM_VERSION_MAJOR
13821 			 && (minor < VIM_VERSION_MINOR
13822 			     || (minor == VIM_VERSION_MINOR
13823 				 && has_patch(atoi((char *)name + 10))))));
13824 	    }
13825 	    else
13826 		n = has_patch(atoi((char *)name + 5));
13827 	}
13828 	else if (STRICMP(name, "vim_starting") == 0)
13829 	    n = (starting != 0);
13830 #ifdef FEAT_MBYTE
13831 	else if (STRICMP(name, "multi_byte_encoding") == 0)
13832 	    n = has_mbyte;
13833 #endif
13834 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32)
13835 	else if (STRICMP(name, "balloon_multiline") == 0)
13836 	    n = multiline_balloon_available();
13837 #endif
13838 #ifdef DYNAMIC_TCL
13839 	else if (STRICMP(name, "tcl") == 0)
13840 	    n = tcl_enabled(FALSE);
13841 #endif
13842 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
13843 	else if (STRICMP(name, "iconv") == 0)
13844 	    n = iconv_enabled(FALSE);
13845 #endif
13846 #ifdef DYNAMIC_LUA
13847 	else if (STRICMP(name, "lua") == 0)
13848 	    n = lua_enabled(FALSE);
13849 #endif
13850 #ifdef DYNAMIC_MZSCHEME
13851 	else if (STRICMP(name, "mzscheme") == 0)
13852 	    n = mzscheme_enabled(FALSE);
13853 #endif
13854 #ifdef DYNAMIC_RUBY
13855 	else if (STRICMP(name, "ruby") == 0)
13856 	    n = ruby_enabled(FALSE);
13857 #endif
13858 #ifdef FEAT_PYTHON
13859 #ifdef DYNAMIC_PYTHON
13860 	else if (STRICMP(name, "python") == 0)
13861 	    n = python_enabled(FALSE);
13862 #endif
13863 #endif
13864 #ifdef FEAT_PYTHON3
13865 #ifdef DYNAMIC_PYTHON3
13866 	else if (STRICMP(name, "python3") == 0)
13867 	    n = python3_enabled(FALSE);
13868 #endif
13869 #endif
13870 #ifdef DYNAMIC_PERL
13871 	else if (STRICMP(name, "perl") == 0)
13872 	    n = perl_enabled(FALSE);
13873 #endif
13874 #ifdef FEAT_GUI
13875 	else if (STRICMP(name, "gui_running") == 0)
13876 	    n = (gui.in_use || gui.starting);
13877 # ifdef FEAT_GUI_W32
13878 	else if (STRICMP(name, "gui_win32s") == 0)
13879 	    n = gui_is_win32s();
13880 # endif
13881 # ifdef FEAT_BROWSE
13882 	else if (STRICMP(name, "browse") == 0)
13883 	    n = gui.in_use;	/* gui_mch_browse() works when GUI is running */
13884 # endif
13885 #endif
13886 #ifdef FEAT_SYN_HL
13887 	else if (STRICMP(name, "syntax_items") == 0)
13888 	    n = syntax_present(curwin);
13889 #endif
13890 #if defined(WIN3264)
13891 	else if (STRICMP(name, "win95") == 0)
13892 	    n = mch_windows95();
13893 #endif
13894 #ifdef FEAT_NETBEANS_INTG
13895 	else if (STRICMP(name, "netbeans_enabled") == 0)
13896 	    n = netbeans_active();
13897 #endif
13898     }
13899 
13900     rettv->vval.v_number = n;
13901 }
13902 
13903 /*
13904  * "has_key()" function
13905  */
13906     static void
13907 f_has_key(typval_T *argvars, typval_T *rettv)
13908 {
13909     if (argvars[0].v_type != VAR_DICT)
13910     {
13911 	EMSG(_(e_dictreq));
13912 	return;
13913     }
13914     if (argvars[0].vval.v_dict == NULL)
13915 	return;
13916 
13917     rettv->vval.v_number = dict_find(argvars[0].vval.v_dict,
13918 				      get_tv_string(&argvars[1]), -1) != NULL;
13919 }
13920 
13921 /*
13922  * "haslocaldir()" function
13923  */
13924     static void
13925 f_haslocaldir(typval_T *argvars, typval_T *rettv)
13926 {
13927     win_T	*wp = NULL;
13928 
13929     wp = find_tabwin(&argvars[0], &argvars[1]);
13930     rettv->vval.v_number = (wp != NULL && wp->w_localdir != NULL);
13931 }
13932 
13933 /*
13934  * "hasmapto()" function
13935  */
13936     static void
13937 f_hasmapto(typval_T *argvars, typval_T *rettv)
13938 {
13939     char_u	*name;
13940     char_u	*mode;
13941     char_u	buf[NUMBUFLEN];
13942     int		abbr = FALSE;
13943 
13944     name = get_tv_string(&argvars[0]);
13945     if (argvars[1].v_type == VAR_UNKNOWN)
13946 	mode = (char_u *)"nvo";
13947     else
13948     {
13949 	mode = get_tv_string_buf(&argvars[1], buf);
13950 	if (argvars[2].v_type != VAR_UNKNOWN)
13951 	    abbr = get_tv_number(&argvars[2]);
13952     }
13953 
13954     if (map_to_exists(name, mode, abbr))
13955 	rettv->vval.v_number = TRUE;
13956     else
13957 	rettv->vval.v_number = FALSE;
13958 }
13959 
13960 /*
13961  * "histadd()" function
13962  */
13963     static void
13964 f_histadd(typval_T *argvars UNUSED, typval_T *rettv)
13965 {
13966 #ifdef FEAT_CMDHIST
13967     int		histype;
13968     char_u	*str;
13969     char_u	buf[NUMBUFLEN];
13970 #endif
13971 
13972     rettv->vval.v_number = FALSE;
13973     if (check_restricted() || check_secure())
13974 	return;
13975 #ifdef FEAT_CMDHIST
13976     str = get_tv_string_chk(&argvars[0]);	/* NULL on type error */
13977     histype = str != NULL ? get_histtype(str) : -1;
13978     if (histype >= 0)
13979     {
13980 	str = get_tv_string_buf(&argvars[1], buf);
13981 	if (*str != NUL)
13982 	{
13983 	    init_history();
13984 	    add_to_history(histype, str, FALSE, NUL);
13985 	    rettv->vval.v_number = TRUE;
13986 	    return;
13987 	}
13988     }
13989 #endif
13990 }
13991 
13992 /*
13993  * "histdel()" function
13994  */
13995     static void
13996 f_histdel(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
13997 {
13998 #ifdef FEAT_CMDHIST
13999     int		n;
14000     char_u	buf[NUMBUFLEN];
14001     char_u	*str;
14002 
14003     str = get_tv_string_chk(&argvars[0]);	/* NULL on type error */
14004     if (str == NULL)
14005 	n = 0;
14006     else if (argvars[1].v_type == VAR_UNKNOWN)
14007 	/* only one argument: clear entire history */
14008 	n = clr_history(get_histtype(str));
14009     else if (argvars[1].v_type == VAR_NUMBER)
14010 	/* index given: remove that entry */
14011 	n = del_history_idx(get_histtype(str),
14012 					  (int)get_tv_number(&argvars[1]));
14013     else
14014 	/* string given: remove all matching entries */
14015 	n = del_history_entry(get_histtype(str),
14016 				      get_tv_string_buf(&argvars[1], buf));
14017     rettv->vval.v_number = n;
14018 #endif
14019 }
14020 
14021 /*
14022  * "histget()" function
14023  */
14024     static void
14025 f_histget(typval_T *argvars UNUSED, typval_T *rettv)
14026 {
14027 #ifdef FEAT_CMDHIST
14028     int		type;
14029     int		idx;
14030     char_u	*str;
14031 
14032     str = get_tv_string_chk(&argvars[0]);	/* NULL on type error */
14033     if (str == NULL)
14034 	rettv->vval.v_string = NULL;
14035     else
14036     {
14037 	type = get_histtype(str);
14038 	if (argvars[1].v_type == VAR_UNKNOWN)
14039 	    idx = get_history_idx(type);
14040 	else
14041 	    idx = (int)get_tv_number_chk(&argvars[1], NULL);
14042 						    /* -1 on type error */
14043 	rettv->vval.v_string = vim_strsave(get_history_entry(type, idx));
14044     }
14045 #else
14046     rettv->vval.v_string = NULL;
14047 #endif
14048     rettv->v_type = VAR_STRING;
14049 }
14050 
14051 /*
14052  * "histnr()" function
14053  */
14054     static void
14055 f_histnr(typval_T *argvars UNUSED, typval_T *rettv)
14056 {
14057     int		i;
14058 
14059 #ifdef FEAT_CMDHIST
14060     char_u	*history = get_tv_string_chk(&argvars[0]);
14061 
14062     i = history == NULL ? HIST_CMD - 1 : get_histtype(history);
14063     if (i >= HIST_CMD && i < HIST_COUNT)
14064 	i = get_history_idx(i);
14065     else
14066 #endif
14067 	i = -1;
14068     rettv->vval.v_number = i;
14069 }
14070 
14071 /*
14072  * "highlightID(name)" function
14073  */
14074     static void
14075 f_hlID(typval_T *argvars, typval_T *rettv)
14076 {
14077     rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0]));
14078 }
14079 
14080 /*
14081  * "highlight_exists()" function
14082  */
14083     static void
14084 f_hlexists(typval_T *argvars, typval_T *rettv)
14085 {
14086     rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0]));
14087 }
14088 
14089 /*
14090  * "hostname()" function
14091  */
14092     static void
14093 f_hostname(typval_T *argvars UNUSED, typval_T *rettv)
14094 {
14095     char_u hostname[256];
14096 
14097     mch_get_host_name(hostname, 256);
14098     rettv->v_type = VAR_STRING;
14099     rettv->vval.v_string = vim_strsave(hostname);
14100 }
14101 
14102 /*
14103  * iconv() function
14104  */
14105     static void
14106 f_iconv(typval_T *argvars UNUSED, typval_T *rettv)
14107 {
14108 #ifdef FEAT_MBYTE
14109     char_u	buf1[NUMBUFLEN];
14110     char_u	buf2[NUMBUFLEN];
14111     char_u	*from, *to, *str;
14112     vimconv_T	vimconv;
14113 #endif
14114 
14115     rettv->v_type = VAR_STRING;
14116     rettv->vval.v_string = NULL;
14117 
14118 #ifdef FEAT_MBYTE
14119     str = get_tv_string(&argvars[0]);
14120     from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1)));
14121     to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2)));
14122     vimconv.vc_type = CONV_NONE;
14123     convert_setup(&vimconv, from, to);
14124 
14125     /* If the encodings are equal, no conversion needed. */
14126     if (vimconv.vc_type == CONV_NONE)
14127 	rettv->vval.v_string = vim_strsave(str);
14128     else
14129 	rettv->vval.v_string = string_convert(&vimconv, str, NULL);
14130 
14131     convert_setup(&vimconv, NULL, NULL);
14132     vim_free(from);
14133     vim_free(to);
14134 #endif
14135 }
14136 
14137 /*
14138  * "indent()" function
14139  */
14140     static void
14141 f_indent(typval_T *argvars, typval_T *rettv)
14142 {
14143     linenr_T	lnum;
14144 
14145     lnum = get_tv_lnum(argvars);
14146     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
14147 	rettv->vval.v_number = get_indent_lnum(lnum);
14148     else
14149 	rettv->vval.v_number = -1;
14150 }
14151 
14152 /*
14153  * "index()" function
14154  */
14155     static void
14156 f_index(typval_T *argvars, typval_T *rettv)
14157 {
14158     list_T	*l;
14159     listitem_T	*item;
14160     long	idx = 0;
14161     int		ic = FALSE;
14162 
14163     rettv->vval.v_number = -1;
14164     if (argvars[0].v_type != VAR_LIST)
14165     {
14166 	EMSG(_(e_listreq));
14167 	return;
14168     }
14169     l = argvars[0].vval.v_list;
14170     if (l != NULL)
14171     {
14172 	item = l->lv_first;
14173 	if (argvars[2].v_type != VAR_UNKNOWN)
14174 	{
14175 	    int		error = FALSE;
14176 
14177 	    /* Start at specified item.  Use the cached index that list_find()
14178 	     * sets, so that a negative number also works. */
14179 	    item = list_find(l, get_tv_number_chk(&argvars[2], &error));
14180 	    idx = l->lv_idx;
14181 	    if (argvars[3].v_type != VAR_UNKNOWN)
14182 		ic = get_tv_number_chk(&argvars[3], &error);
14183 	    if (error)
14184 		item = NULL;
14185 	}
14186 
14187 	for ( ; item != NULL; item = item->li_next, ++idx)
14188 	    if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE))
14189 	    {
14190 		rettv->vval.v_number = idx;
14191 		break;
14192 	    }
14193     }
14194 }
14195 
14196 static int inputsecret_flag = 0;
14197 
14198 static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog);
14199 
14200 /*
14201  * This function is used by f_input() and f_inputdialog() functions. The third
14202  * argument to f_input() specifies the type of completion to use at the
14203  * prompt. The third argument to f_inputdialog() specifies the value to return
14204  * when the user cancels the prompt.
14205  */
14206     static void
14207 get_user_input(
14208     typval_T	*argvars,
14209     typval_T	*rettv,
14210     int		inputdialog)
14211 {
14212     char_u	*prompt = get_tv_string_chk(&argvars[0]);
14213     char_u	*p = NULL;
14214     int		c;
14215     char_u	buf[NUMBUFLEN];
14216     int		cmd_silent_save = cmd_silent;
14217     char_u	*defstr = (char_u *)"";
14218     int		xp_type = EXPAND_NOTHING;
14219     char_u	*xp_arg = NULL;
14220 
14221     rettv->v_type = VAR_STRING;
14222     rettv->vval.v_string = NULL;
14223 
14224 #ifdef NO_CONSOLE_INPUT
14225     /* While starting up, there is no place to enter text. */
14226     if (no_console_input())
14227 	return;
14228 #endif
14229 
14230     cmd_silent = FALSE;		/* Want to see the prompt. */
14231     if (prompt != NULL)
14232     {
14233 	/* Only the part of the message after the last NL is considered as
14234 	 * prompt for the command line */
14235 	p = vim_strrchr(prompt, '\n');
14236 	if (p == NULL)
14237 	    p = prompt;
14238 	else
14239 	{
14240 	    ++p;
14241 	    c = *p;
14242 	    *p = NUL;
14243 	    msg_start();
14244 	    msg_clr_eos();
14245 	    msg_puts_attr(prompt, echo_attr);
14246 	    msg_didout = FALSE;
14247 	    msg_starthere();
14248 	    *p = c;
14249 	}
14250 	cmdline_row = msg_row;
14251 
14252 	if (argvars[1].v_type != VAR_UNKNOWN)
14253 	{
14254 	    defstr = get_tv_string_buf_chk(&argvars[1], buf);
14255 	    if (defstr != NULL)
14256 		stuffReadbuffSpec(defstr);
14257 
14258 	    if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN)
14259 	    {
14260 		char_u	*xp_name;
14261 		int	xp_namelen;
14262 		long	argt;
14263 
14264 		/* input() with a third argument: completion */
14265 		rettv->vval.v_string = NULL;
14266 
14267 		xp_name = get_tv_string_buf_chk(&argvars[2], buf);
14268 		if (xp_name == NULL)
14269 		    return;
14270 
14271 		xp_namelen = (int)STRLEN(xp_name);
14272 
14273 		if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
14274 							     &xp_arg) == FAIL)
14275 		    return;
14276 	    }
14277 	}
14278 
14279 	if (defstr != NULL)
14280 	{
14281 	    int save_ex_normal_busy = ex_normal_busy;
14282 	    ex_normal_busy = 0;
14283 	    rettv->vval.v_string =
14284 		getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr,
14285 				  xp_type, xp_arg);
14286 	    ex_normal_busy = save_ex_normal_busy;
14287 	}
14288 	if (inputdialog && rettv->vval.v_string == NULL
14289 		&& argvars[1].v_type != VAR_UNKNOWN
14290 		&& argvars[2].v_type != VAR_UNKNOWN)
14291 	    rettv->vval.v_string = vim_strsave(get_tv_string_buf(
14292 							   &argvars[2], buf));
14293 
14294 	vim_free(xp_arg);
14295 
14296 	/* since the user typed this, no need to wait for return */
14297 	need_wait_return = FALSE;
14298 	msg_didout = FALSE;
14299     }
14300     cmd_silent = cmd_silent_save;
14301 }
14302 
14303 /*
14304  * "input()" function
14305  *     Also handles inputsecret() when inputsecret is set.
14306  */
14307     static void
14308 f_input(typval_T *argvars, typval_T *rettv)
14309 {
14310     get_user_input(argvars, rettv, FALSE);
14311 }
14312 
14313 /*
14314  * "inputdialog()" function
14315  */
14316     static void
14317 f_inputdialog(typval_T *argvars, typval_T *rettv)
14318 {
14319 #if defined(FEAT_GUI_TEXTDIALOG)
14320     /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */
14321     if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL)
14322     {
14323 	char_u	*message;
14324 	char_u	buf[NUMBUFLEN];
14325 	char_u	*defstr = (char_u *)"";
14326 
14327 	message = get_tv_string_chk(&argvars[0]);
14328 	if (argvars[1].v_type != VAR_UNKNOWN
14329 		&& (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL)
14330 	    vim_strncpy(IObuff, defstr, IOSIZE - 1);
14331 	else
14332 	    IObuff[0] = NUL;
14333 	if (message != NULL && defstr != NULL
14334 		&& do_dialog(VIM_QUESTION, NULL, message,
14335 			  (char_u *)_("&OK\n&Cancel"), 1, IObuff, FALSE) == 1)
14336 	    rettv->vval.v_string = vim_strsave(IObuff);
14337 	else
14338 	{
14339 	    if (message != NULL && defstr != NULL
14340 					&& argvars[1].v_type != VAR_UNKNOWN
14341 					&& argvars[2].v_type != VAR_UNKNOWN)
14342 		rettv->vval.v_string = vim_strsave(
14343 				      get_tv_string_buf(&argvars[2], buf));
14344 	    else
14345 		rettv->vval.v_string = NULL;
14346 	}
14347 	rettv->v_type = VAR_STRING;
14348     }
14349     else
14350 #endif
14351 	get_user_input(argvars, rettv, TRUE);
14352 }
14353 
14354 /*
14355  * "inputlist()" function
14356  */
14357     static void
14358 f_inputlist(typval_T *argvars, typval_T *rettv)
14359 {
14360     listitem_T	*li;
14361     int		selected;
14362     int		mouse_used;
14363 
14364 #ifdef NO_CONSOLE_INPUT
14365     /* While starting up, there is no place to enter text. */
14366     if (no_console_input())
14367 	return;
14368 #endif
14369     if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL)
14370     {
14371 	EMSG2(_(e_listarg), "inputlist()");
14372 	return;
14373     }
14374 
14375     msg_start();
14376     msg_row = Rows - 1;	/* for when 'cmdheight' > 1 */
14377     lines_left = Rows;	/* avoid more prompt */
14378     msg_scroll = TRUE;
14379     msg_clr_eos();
14380 
14381     for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next)
14382     {
14383 	msg_puts(get_tv_string(&li->li_tv));
14384 	msg_putchar('\n');
14385     }
14386 
14387     /* Ask for choice. */
14388     selected = prompt_for_number(&mouse_used);
14389     if (mouse_used)
14390 	selected -= lines_left;
14391 
14392     rettv->vval.v_number = selected;
14393 }
14394 
14395 
14396 static garray_T	    ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL};
14397 
14398 /*
14399  * "inputrestore()" function
14400  */
14401     static void
14402 f_inputrestore(typval_T *argvars UNUSED, typval_T *rettv)
14403 {
14404     if (ga_userinput.ga_len > 0)
14405     {
14406 	--ga_userinput.ga_len;
14407 	restore_typeahead((tasave_T *)(ga_userinput.ga_data)
14408 						       + ga_userinput.ga_len);
14409 	/* default return is zero == OK */
14410     }
14411     else if (p_verbose > 1)
14412     {
14413 	verb_msg((char_u *)_("called inputrestore() more often than inputsave()"));
14414 	rettv->vval.v_number = 1; /* Failed */
14415     }
14416 }
14417 
14418 /*
14419  * "inputsave()" function
14420  */
14421     static void
14422 f_inputsave(typval_T *argvars UNUSED, typval_T *rettv)
14423 {
14424     /* Add an entry to the stack of typeahead storage. */
14425     if (ga_grow(&ga_userinput, 1) == OK)
14426     {
14427 	save_typeahead((tasave_T *)(ga_userinput.ga_data)
14428 						       + ga_userinput.ga_len);
14429 	++ga_userinput.ga_len;
14430 	/* default return is zero == OK */
14431     }
14432     else
14433 	rettv->vval.v_number = 1; /* Failed */
14434 }
14435 
14436 /*
14437  * "inputsecret()" function
14438  */
14439     static void
14440 f_inputsecret(typval_T *argvars, typval_T *rettv)
14441 {
14442     ++cmdline_star;
14443     ++inputsecret_flag;
14444     f_input(argvars, rettv);
14445     --cmdline_star;
14446     --inputsecret_flag;
14447 }
14448 
14449 /*
14450  * "insert()" function
14451  */
14452     static void
14453 f_insert(typval_T *argvars, typval_T *rettv)
14454 {
14455     long	before = 0;
14456     listitem_T	*item;
14457     list_T	*l;
14458     int		error = FALSE;
14459 
14460     if (argvars[0].v_type != VAR_LIST)
14461 	EMSG2(_(e_listarg), "insert()");
14462     else if ((l = argvars[0].vval.v_list) != NULL
14463 	    && !tv_check_lock(l->lv_lock, (char_u *)N_("insert() argument"), TRUE))
14464     {
14465 	if (argvars[2].v_type != VAR_UNKNOWN)
14466 	    before = get_tv_number_chk(&argvars[2], &error);
14467 	if (error)
14468 	    return;		/* type error; errmsg already given */
14469 
14470 	if (before == l->lv_len)
14471 	    item = NULL;
14472 	else
14473 	{
14474 	    item = list_find(l, before);
14475 	    if (item == NULL)
14476 	    {
14477 		EMSGN(_(e_listidx), before);
14478 		l = NULL;
14479 	    }
14480 	}
14481 	if (l != NULL)
14482 	{
14483 	    list_insert_tv(l, &argvars[1], item);
14484 	    copy_tv(&argvars[0], rettv);
14485 	}
14486     }
14487 }
14488 
14489 /*
14490  * "invert(expr)" function
14491  */
14492     static void
14493 f_invert(typval_T *argvars, typval_T *rettv)
14494 {
14495     rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL);
14496 }
14497 
14498 /*
14499  * "isdirectory()" function
14500  */
14501     static void
14502 f_isdirectory(typval_T *argvars, typval_T *rettv)
14503 {
14504     rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0]));
14505 }
14506 
14507 /*
14508  * "islocked()" function
14509  */
14510     static void
14511 f_islocked(typval_T *argvars, typval_T *rettv)
14512 {
14513     lval_T	lv;
14514     char_u	*end;
14515     dictitem_T	*di;
14516 
14517     rettv->vval.v_number = -1;
14518     end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE,
14519 					GLV_NO_AUTOLOAD, FNE_CHECK_START);
14520     if (end != NULL && lv.ll_name != NULL)
14521     {
14522 	if (*end != NUL)
14523 	    EMSG(_(e_trailing));
14524 	else
14525 	{
14526 	    if (lv.ll_tv == NULL)
14527 	    {
14528 		if (check_changedtick(lv.ll_name))
14529 		    rettv->vval.v_number = 1;	    /* always locked */
14530 		else
14531 		{
14532 		    di = find_var(lv.ll_name, NULL, TRUE);
14533 		    if (di != NULL)
14534 		    {
14535 			/* Consider a variable locked when:
14536 			 * 1. the variable itself is locked
14537 			 * 2. the value of the variable is locked.
14538 			 * 3. the List or Dict value is locked.
14539 			 */
14540 			rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
14541 						  || tv_islocked(&di->di_tv));
14542 		    }
14543 		}
14544 	    }
14545 	    else if (lv.ll_range)
14546 		EMSG(_("E786: Range not allowed"));
14547 	    else if (lv.ll_newkey != NULL)
14548 		EMSG2(_(e_dictkey), lv.ll_newkey);
14549 	    else if (lv.ll_list != NULL)
14550 		/* List item. */
14551 		rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv);
14552 	    else
14553 		/* Dictionary item. */
14554 		rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv);
14555 	}
14556     }
14557 
14558     clear_lval(&lv);
14559 }
14560 
14561 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
14562 /*
14563  * "isnan()" function
14564  */
14565     static void
14566 f_isnan(typval_T *argvars, typval_T *rettv)
14567 {
14568     rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT
14569 					    && isnan(argvars[0].vval.v_float);
14570 }
14571 #endif
14572 
14573 static void dict_list(typval_T *argvars, typval_T *rettv, int what);
14574 
14575 /*
14576  * Turn a dict into a list:
14577  * "what" == 0: list of keys
14578  * "what" == 1: list of values
14579  * "what" == 2: list of items
14580  */
14581     static void
14582 dict_list(typval_T *argvars, typval_T *rettv, int what)
14583 {
14584     list_T	*l2;
14585     dictitem_T	*di;
14586     hashitem_T	*hi;
14587     listitem_T	*li;
14588     listitem_T	*li2;
14589     dict_T	*d;
14590     int		todo;
14591 
14592     if (argvars[0].v_type != VAR_DICT)
14593     {
14594 	EMSG(_(e_dictreq));
14595 	return;
14596     }
14597     if ((d = argvars[0].vval.v_dict) == NULL)
14598 	return;
14599 
14600     if (rettv_list_alloc(rettv) == FAIL)
14601 	return;
14602 
14603     todo = (int)d->dv_hashtab.ht_used;
14604     for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
14605     {
14606 	if (!HASHITEM_EMPTY(hi))
14607 	{
14608 	    --todo;
14609 	    di = HI2DI(hi);
14610 
14611 	    li = listitem_alloc();
14612 	    if (li == NULL)
14613 		break;
14614 	    list_append(rettv->vval.v_list, li);
14615 
14616 	    if (what == 0)
14617 	    {
14618 		/* keys() */
14619 		li->li_tv.v_type = VAR_STRING;
14620 		li->li_tv.v_lock = 0;
14621 		li->li_tv.vval.v_string = vim_strsave(di->di_key);
14622 	    }
14623 	    else if (what == 1)
14624 	    {
14625 		/* values() */
14626 		copy_tv(&di->di_tv, &li->li_tv);
14627 	    }
14628 	    else
14629 	    {
14630 		/* items() */
14631 		l2 = list_alloc();
14632 		li->li_tv.v_type = VAR_LIST;
14633 		li->li_tv.v_lock = 0;
14634 		li->li_tv.vval.v_list = l2;
14635 		if (l2 == NULL)
14636 		    break;
14637 		++l2->lv_refcount;
14638 
14639 		li2 = listitem_alloc();
14640 		if (li2 == NULL)
14641 		    break;
14642 		list_append(l2, li2);
14643 		li2->li_tv.v_type = VAR_STRING;
14644 		li2->li_tv.v_lock = 0;
14645 		li2->li_tv.vval.v_string = vim_strsave(di->di_key);
14646 
14647 		li2 = listitem_alloc();
14648 		if (li2 == NULL)
14649 		    break;
14650 		list_append(l2, li2);
14651 		copy_tv(&di->di_tv, &li2->li_tv);
14652 	    }
14653 	}
14654     }
14655 }
14656 
14657 /*
14658  * "items(dict)" function
14659  */
14660     static void
14661 f_items(typval_T *argvars, typval_T *rettv)
14662 {
14663     dict_list(argvars, rettv, 2);
14664 }
14665 
14666 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
14667 /*
14668  * Get the job from the argument.
14669  * Returns NULL if the job is invalid.
14670  */
14671     static job_T *
14672 get_job_arg(typval_T *tv)
14673 {
14674     job_T *job;
14675 
14676     if (tv->v_type != VAR_JOB)
14677     {
14678 	EMSG2(_(e_invarg2), get_tv_string(tv));
14679 	return NULL;
14680     }
14681     job = tv->vval.v_job;
14682 
14683     if (job == NULL)
14684 	EMSG(_("E916: not a valid job"));
14685     return job;
14686 }
14687 
14688 /*
14689  * "job_getchannel()" function
14690  */
14691     static void
14692 f_job_getchannel(typval_T *argvars, typval_T *rettv)
14693 {
14694     job_T	*job = get_job_arg(&argvars[0]);
14695 
14696     if (job != NULL)
14697     {
14698 	rettv->v_type = VAR_CHANNEL;
14699 	rettv->vval.v_channel = job->jv_channel;
14700 	if (job->jv_channel != NULL)
14701 	    ++job->jv_channel->ch_refcount;
14702     }
14703 }
14704 
14705 /*
14706  * "job_info()" function
14707  */
14708     static void
14709 f_job_info(typval_T *argvars, typval_T *rettv)
14710 {
14711     job_T	*job = get_job_arg(&argvars[0]);
14712 
14713     if (job != NULL && rettv_dict_alloc(rettv) != FAIL)
14714 	job_info(job, rettv->vval.v_dict);
14715 }
14716 
14717 /*
14718  * "job_setoptions()" function
14719  */
14720     static void
14721 f_job_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
14722 {
14723     job_T	*job = get_job_arg(&argvars[0]);
14724     jobopt_T	opt;
14725 
14726     if (job == NULL)
14727 	return;
14728     clear_job_options(&opt);
14729     if (get_job_options(&argvars[1], &opt, JO_STOPONEXIT + JO_EXIT_CB) == FAIL)
14730 	return;
14731     job_set_options(job, &opt);
14732 }
14733 
14734 /*
14735  * "job_start()" function
14736  */
14737     static void
14738 f_job_start(typval_T *argvars, typval_T *rettv)
14739 {
14740     rettv->v_type = VAR_JOB;
14741     rettv->vval.v_job = job_start(argvars);
14742 }
14743 
14744 /*
14745  * "job_status()" function
14746  */
14747     static void
14748 f_job_status(typval_T *argvars, typval_T *rettv)
14749 {
14750     job_T	*job = get_job_arg(&argvars[0]);
14751 
14752     if (job != NULL)
14753     {
14754 	rettv->v_type = VAR_STRING;
14755 	rettv->vval.v_string = vim_strsave((char_u *)job_status(job));
14756     }
14757 }
14758 
14759 /*
14760  * "job_stop()" function
14761  */
14762     static void
14763 f_job_stop(typval_T *argvars, typval_T *rettv)
14764 {
14765     job_T	*job = get_job_arg(&argvars[0]);
14766 
14767     if (job != NULL)
14768 	rettv->vval.v_number = job_stop(job, argvars);
14769 }
14770 #endif
14771 
14772 /*
14773  * "join()" function
14774  */
14775     static void
14776 f_join(typval_T *argvars, typval_T *rettv)
14777 {
14778     garray_T	ga;
14779     char_u	*sep;
14780 
14781     if (argvars[0].v_type != VAR_LIST)
14782     {
14783 	EMSG(_(e_listreq));
14784 	return;
14785     }
14786     if (argvars[0].vval.v_list == NULL)
14787 	return;
14788     if (argvars[1].v_type == VAR_UNKNOWN)
14789 	sep = (char_u *)" ";
14790     else
14791 	sep = get_tv_string_chk(&argvars[1]);
14792 
14793     rettv->v_type = VAR_STRING;
14794 
14795     if (sep != NULL)
14796     {
14797 	ga_init2(&ga, (int)sizeof(char), 80);
14798 	list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0);
14799 	ga_append(&ga, NUL);
14800 	rettv->vval.v_string = (char_u *)ga.ga_data;
14801     }
14802     else
14803 	rettv->vval.v_string = NULL;
14804 }
14805 
14806 /*
14807  * "js_decode()" function
14808  */
14809     static void
14810 f_js_decode(typval_T *argvars, typval_T *rettv)
14811 {
14812     js_read_T	reader;
14813 
14814     reader.js_buf = get_tv_string(&argvars[0]);
14815     reader.js_fill = NULL;
14816     reader.js_used = 0;
14817     if (json_decode_all(&reader, rettv, JSON_JS) != OK)
14818 	EMSG(_(e_invarg));
14819 }
14820 
14821 /*
14822  * "js_encode()" function
14823  */
14824     static void
14825 f_js_encode(typval_T *argvars, typval_T *rettv)
14826 {
14827     rettv->v_type = VAR_STRING;
14828     rettv->vval.v_string = json_encode(&argvars[0], JSON_JS);
14829 }
14830 
14831 /*
14832  * "json_decode()" function
14833  */
14834     static void
14835 f_json_decode(typval_T *argvars, typval_T *rettv)
14836 {
14837     js_read_T	reader;
14838 
14839     reader.js_buf = get_tv_string(&argvars[0]);
14840     reader.js_fill = NULL;
14841     reader.js_used = 0;
14842     if (json_decode_all(&reader, rettv, 0) != OK)
14843 	EMSG(_(e_invarg));
14844 }
14845 
14846 /*
14847  * "json_encode()" function
14848  */
14849     static void
14850 f_json_encode(typval_T *argvars, typval_T *rettv)
14851 {
14852     rettv->v_type = VAR_STRING;
14853     rettv->vval.v_string = json_encode(&argvars[0], 0);
14854 }
14855 
14856 /*
14857  * "keys()" function
14858  */
14859     static void
14860 f_keys(typval_T *argvars, typval_T *rettv)
14861 {
14862     dict_list(argvars, rettv, 0);
14863 }
14864 
14865 /*
14866  * "last_buffer_nr()" function.
14867  */
14868     static void
14869 f_last_buffer_nr(typval_T *argvars UNUSED, typval_T *rettv)
14870 {
14871     int		n = 0;
14872     buf_T	*buf;
14873 
14874     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
14875 	if (n < buf->b_fnum)
14876 	    n = buf->b_fnum;
14877 
14878     rettv->vval.v_number = n;
14879 }
14880 
14881 /*
14882  * "len()" function
14883  */
14884     static void
14885 f_len(typval_T *argvars, typval_T *rettv)
14886 {
14887     switch (argvars[0].v_type)
14888     {
14889 	case VAR_STRING:
14890 	case VAR_NUMBER:
14891 	    rettv->vval.v_number = (varnumber_T)STRLEN(
14892 					       get_tv_string(&argvars[0]));
14893 	    break;
14894 	case VAR_LIST:
14895 	    rettv->vval.v_number = list_len(argvars[0].vval.v_list);
14896 	    break;
14897 	case VAR_DICT:
14898 	    rettv->vval.v_number = dict_len(argvars[0].vval.v_dict);
14899 	    break;
14900 	case VAR_UNKNOWN:
14901 	case VAR_SPECIAL:
14902 	case VAR_FLOAT:
14903 	case VAR_FUNC:
14904 	case VAR_PARTIAL:
14905 	case VAR_JOB:
14906 	case VAR_CHANNEL:
14907 	    EMSG(_("E701: Invalid type for len()"));
14908 	    break;
14909     }
14910 }
14911 
14912 static void libcall_common(typval_T *argvars, typval_T *rettv, int type);
14913 
14914     static void
14915 libcall_common(typval_T *argvars, typval_T *rettv, int type)
14916 {
14917 #ifdef FEAT_LIBCALL
14918     char_u		*string_in;
14919     char_u		**string_result;
14920     int			nr_result;
14921 #endif
14922 
14923     rettv->v_type = type;
14924     if (type != VAR_NUMBER)
14925 	rettv->vval.v_string = NULL;
14926 
14927     if (check_restricted() || check_secure())
14928 	return;
14929 
14930 #ifdef FEAT_LIBCALL
14931     /* The first two args must be strings, otherwise its meaningless */
14932     if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING)
14933     {
14934 	string_in = NULL;
14935 	if (argvars[2].v_type == VAR_STRING)
14936 	    string_in = argvars[2].vval.v_string;
14937 	if (type == VAR_NUMBER)
14938 	    string_result = NULL;
14939 	else
14940 	    string_result = &rettv->vval.v_string;
14941 	if (mch_libcall(argvars[0].vval.v_string,
14942 			     argvars[1].vval.v_string,
14943 			     string_in,
14944 			     argvars[2].vval.v_number,
14945 			     string_result,
14946 			     &nr_result) == OK
14947 		&& type == VAR_NUMBER)
14948 	    rettv->vval.v_number = nr_result;
14949     }
14950 #endif
14951 }
14952 
14953 /*
14954  * "libcall()" function
14955  */
14956     static void
14957 f_libcall(typval_T *argvars, typval_T *rettv)
14958 {
14959     libcall_common(argvars, rettv, VAR_STRING);
14960 }
14961 
14962 /*
14963  * "libcallnr()" function
14964  */
14965     static void
14966 f_libcallnr(typval_T *argvars, typval_T *rettv)
14967 {
14968     libcall_common(argvars, rettv, VAR_NUMBER);
14969 }
14970 
14971 /*
14972  * "line(string)" function
14973  */
14974     static void
14975 f_line(typval_T *argvars, typval_T *rettv)
14976 {
14977     linenr_T	lnum = 0;
14978     pos_T	*fp;
14979     int		fnum;
14980 
14981     fp = var2fpos(&argvars[0], TRUE, &fnum);
14982     if (fp != NULL)
14983 	lnum = fp->lnum;
14984     rettv->vval.v_number = lnum;
14985 }
14986 
14987 /*
14988  * "line2byte(lnum)" function
14989  */
14990     static void
14991 f_line2byte(typval_T *argvars UNUSED, typval_T *rettv)
14992 {
14993 #ifndef FEAT_BYTEOFF
14994     rettv->vval.v_number = -1;
14995 #else
14996     linenr_T	lnum;
14997 
14998     lnum = get_tv_lnum(argvars);
14999     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
15000 	rettv->vval.v_number = -1;
15001     else
15002 	rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL);
15003     if (rettv->vval.v_number >= 0)
15004 	++rettv->vval.v_number;
15005 #endif
15006 }
15007 
15008 /*
15009  * "lispindent(lnum)" function
15010  */
15011     static void
15012 f_lispindent(typval_T *argvars UNUSED, typval_T *rettv)
15013 {
15014 #ifdef FEAT_LISP
15015     pos_T	pos;
15016     linenr_T	lnum;
15017 
15018     pos = curwin->w_cursor;
15019     lnum = get_tv_lnum(argvars);
15020     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
15021     {
15022 	curwin->w_cursor.lnum = lnum;
15023 	rettv->vval.v_number = get_lisp_indent();
15024 	curwin->w_cursor = pos;
15025     }
15026     else
15027 #endif
15028 	rettv->vval.v_number = -1;
15029 }
15030 
15031 /*
15032  * "localtime()" function
15033  */
15034     static void
15035 f_localtime(typval_T *argvars UNUSED, typval_T *rettv)
15036 {
15037     rettv->vval.v_number = (varnumber_T)time(NULL);
15038 }
15039 
15040 static void get_maparg(typval_T *argvars, typval_T *rettv, int exact);
15041 
15042     static void
15043 get_maparg(typval_T *argvars, typval_T *rettv, int exact)
15044 {
15045     char_u	*keys;
15046     char_u	*which;
15047     char_u	buf[NUMBUFLEN];
15048     char_u	*keys_buf = NULL;
15049     char_u	*rhs;
15050     int		mode;
15051     int		abbr = FALSE;
15052     int		get_dict = FALSE;
15053     mapblock_T	*mp;
15054     int		buffer_local;
15055 
15056     /* return empty string for failure */
15057     rettv->v_type = VAR_STRING;
15058     rettv->vval.v_string = NULL;
15059 
15060     keys = get_tv_string(&argvars[0]);
15061     if (*keys == NUL)
15062 	return;
15063 
15064     if (argvars[1].v_type != VAR_UNKNOWN)
15065     {
15066 	which = get_tv_string_buf_chk(&argvars[1], buf);
15067 	if (argvars[2].v_type != VAR_UNKNOWN)
15068 	{
15069 	    abbr = get_tv_number(&argvars[2]);
15070 	    if (argvars[3].v_type != VAR_UNKNOWN)
15071 		get_dict = get_tv_number(&argvars[3]);
15072 	}
15073     }
15074     else
15075 	which = (char_u *)"";
15076     if (which == NULL)
15077 	return;
15078 
15079     mode = get_map_mode(&which, 0);
15080 
15081     keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE);
15082     rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local);
15083     vim_free(keys_buf);
15084 
15085     if (!get_dict)
15086     {
15087 	/* Return a string. */
15088 	if (rhs != NULL)
15089 	    rettv->vval.v_string = str2special_save(rhs, FALSE);
15090 
15091     }
15092     else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL)
15093     {
15094 	/* Return a dictionary. */
15095 	char_u	    *lhs = str2special_save(mp->m_keys, TRUE);
15096 	char_u	    *mapmode = map_mode_to_chars(mp->m_mode);
15097 	dict_T	    *dict = rettv->vval.v_dict;
15098 
15099 	dict_add_nr_str(dict, "lhs",	 0L, lhs);
15100 	dict_add_nr_str(dict, "rhs",     0L, mp->m_orig_str);
15101 	dict_add_nr_str(dict, "noremap", mp->m_noremap ? 1L : 0L , NULL);
15102 	dict_add_nr_str(dict, "expr",    mp->m_expr    ? 1L : 0L, NULL);
15103 	dict_add_nr_str(dict, "silent",  mp->m_silent  ? 1L : 0L, NULL);
15104 	dict_add_nr_str(dict, "sid",     (long)mp->m_script_ID, NULL);
15105 	dict_add_nr_str(dict, "buffer",  (long)buffer_local, NULL);
15106 	dict_add_nr_str(dict, "nowait",  mp->m_nowait  ? 1L : 0L, NULL);
15107 	dict_add_nr_str(dict, "mode",    0L, mapmode);
15108 
15109 	vim_free(lhs);
15110 	vim_free(mapmode);
15111     }
15112 }
15113 
15114 #ifdef FEAT_FLOAT
15115 /*
15116  * "log()" function
15117  */
15118     static void
15119 f_log(typval_T *argvars, typval_T *rettv)
15120 {
15121     float_T	f = 0.0;
15122 
15123     rettv->v_type = VAR_FLOAT;
15124     if (get_float_arg(argvars, &f) == OK)
15125 	rettv->vval.v_float = log(f);
15126     else
15127 	rettv->vval.v_float = 0.0;
15128 }
15129 
15130 /*
15131  * "log10()" function
15132  */
15133     static void
15134 f_log10(typval_T *argvars, typval_T *rettv)
15135 {
15136     float_T	f = 0.0;
15137 
15138     rettv->v_type = VAR_FLOAT;
15139     if (get_float_arg(argvars, &f) == OK)
15140 	rettv->vval.v_float = log10(f);
15141     else
15142 	rettv->vval.v_float = 0.0;
15143 }
15144 #endif
15145 
15146 #ifdef FEAT_LUA
15147 /*
15148  * "luaeval()" function
15149  */
15150     static void
15151 f_luaeval(typval_T *argvars, typval_T *rettv)
15152 {
15153     char_u	*str;
15154     char_u	buf[NUMBUFLEN];
15155 
15156     str = get_tv_string_buf(&argvars[0], buf);
15157     do_luaeval(str, argvars + 1, rettv);
15158 }
15159 #endif
15160 
15161 /*
15162  * "map()" function
15163  */
15164     static void
15165 f_map(typval_T *argvars, typval_T *rettv)
15166 {
15167     filter_map(argvars, rettv, TRUE);
15168 }
15169 
15170 /*
15171  * "maparg()" function
15172  */
15173     static void
15174 f_maparg(typval_T *argvars, typval_T *rettv)
15175 {
15176     get_maparg(argvars, rettv, TRUE);
15177 }
15178 
15179 /*
15180  * "mapcheck()" function
15181  */
15182     static void
15183 f_mapcheck(typval_T *argvars, typval_T *rettv)
15184 {
15185     get_maparg(argvars, rettv, FALSE);
15186 }
15187 
15188 static void find_some_match(typval_T *argvars, typval_T *rettv, int start);
15189 
15190     static void
15191 find_some_match(typval_T *argvars, typval_T *rettv, int type)
15192 {
15193     char_u	*str = NULL;
15194     long	len = 0;
15195     char_u	*expr = NULL;
15196     char_u	*pat;
15197     regmatch_T	regmatch;
15198     char_u	patbuf[NUMBUFLEN];
15199     char_u	strbuf[NUMBUFLEN];
15200     char_u	*save_cpo;
15201     long	start = 0;
15202     long	nth = 1;
15203     colnr_T	startcol = 0;
15204     int		match = 0;
15205     list_T	*l = NULL;
15206     listitem_T	*li = NULL;
15207     long	idx = 0;
15208     char_u	*tofree = NULL;
15209 
15210     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
15211     save_cpo = p_cpo;
15212     p_cpo = (char_u *)"";
15213 
15214     rettv->vval.v_number = -1;
15215     if (type == 3)
15216     {
15217 	/* return empty list when there are no matches */
15218 	if (rettv_list_alloc(rettv) == FAIL)
15219 	    goto theend;
15220     }
15221     else if (type == 2)
15222     {
15223 	rettv->v_type = VAR_STRING;
15224 	rettv->vval.v_string = NULL;
15225     }
15226 
15227     if (argvars[0].v_type == VAR_LIST)
15228     {
15229 	if ((l = argvars[0].vval.v_list) == NULL)
15230 	    goto theend;
15231 	li = l->lv_first;
15232     }
15233     else
15234     {
15235 	expr = str = get_tv_string(&argvars[0]);
15236 	len = (long)STRLEN(str);
15237     }
15238 
15239     pat = get_tv_string_buf_chk(&argvars[1], patbuf);
15240     if (pat == NULL)
15241 	goto theend;
15242 
15243     if (argvars[2].v_type != VAR_UNKNOWN)
15244     {
15245 	int	    error = FALSE;
15246 
15247 	start = get_tv_number_chk(&argvars[2], &error);
15248 	if (error)
15249 	    goto theend;
15250 	if (l != NULL)
15251 	{
15252 	    li = list_find(l, start);
15253 	    if (li == NULL)
15254 		goto theend;
15255 	    idx = l->lv_idx;	/* use the cached index */
15256 	}
15257 	else
15258 	{
15259 	    if (start < 0)
15260 		start = 0;
15261 	    if (start > len)
15262 		goto theend;
15263 	    /* When "count" argument is there ignore matches before "start",
15264 	     * otherwise skip part of the string.  Differs when pattern is "^"
15265 	     * or "\<". */
15266 	    if (argvars[3].v_type != VAR_UNKNOWN)
15267 		startcol = start;
15268 	    else
15269 	    {
15270 		str += start;
15271 		len -= start;
15272 	    }
15273 	}
15274 
15275 	if (argvars[3].v_type != VAR_UNKNOWN)
15276 	    nth = get_tv_number_chk(&argvars[3], &error);
15277 	if (error)
15278 	    goto theend;
15279     }
15280 
15281     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
15282     if (regmatch.regprog != NULL)
15283     {
15284 	regmatch.rm_ic = p_ic;
15285 
15286 	for (;;)
15287 	{
15288 	    if (l != NULL)
15289 	    {
15290 		if (li == NULL)
15291 		{
15292 		    match = FALSE;
15293 		    break;
15294 		}
15295 		vim_free(tofree);
15296 		str = echo_string(&li->li_tv, &tofree, strbuf, 0);
15297 		if (str == NULL)
15298 		    break;
15299 	    }
15300 
15301 	    match = vim_regexec_nl(&regmatch, str, (colnr_T)startcol);
15302 
15303 	    if (match && --nth <= 0)
15304 		break;
15305 	    if (l == NULL && !match)
15306 		break;
15307 
15308 	    /* Advance to just after the match. */
15309 	    if (l != NULL)
15310 	    {
15311 		li = li->li_next;
15312 		++idx;
15313 	    }
15314 	    else
15315 	    {
15316 #ifdef FEAT_MBYTE
15317 		startcol = (colnr_T)(regmatch.startp[0]
15318 				    + (*mb_ptr2len)(regmatch.startp[0]) - str);
15319 #else
15320 		startcol = (colnr_T)(regmatch.startp[0] + 1 - str);
15321 #endif
15322 		if (startcol > (colnr_T)len
15323 				      || str + startcol <= regmatch.startp[0])
15324 		{
15325 		    match = FALSE;
15326 		    break;
15327 		}
15328 	    }
15329 	}
15330 
15331 	if (match)
15332 	{
15333 	    if (type == 3)
15334 	    {
15335 		int i;
15336 
15337 		/* return list with matched string and submatches */
15338 		for (i = 0; i < NSUBEXP; ++i)
15339 		{
15340 		    if (regmatch.endp[i] == NULL)
15341 		    {
15342 			if (list_append_string(rettv->vval.v_list,
15343 						     (char_u *)"", 0) == FAIL)
15344 			    break;
15345 		    }
15346 		    else if (list_append_string(rettv->vval.v_list,
15347 				regmatch.startp[i],
15348 				(int)(regmatch.endp[i] - regmatch.startp[i]))
15349 			    == FAIL)
15350 			break;
15351 		}
15352 	    }
15353 	    else if (type == 2)
15354 	    {
15355 		/* return matched string */
15356 		if (l != NULL)
15357 		    copy_tv(&li->li_tv, rettv);
15358 		else
15359 		    rettv->vval.v_string = vim_strnsave(regmatch.startp[0],
15360 				(int)(regmatch.endp[0] - regmatch.startp[0]));
15361 	    }
15362 	    else if (l != NULL)
15363 		rettv->vval.v_number = idx;
15364 	    else
15365 	    {
15366 		if (type != 0)
15367 		    rettv->vval.v_number =
15368 				      (varnumber_T)(regmatch.startp[0] - str);
15369 		else
15370 		    rettv->vval.v_number =
15371 					(varnumber_T)(regmatch.endp[0] - str);
15372 		rettv->vval.v_number += (varnumber_T)(str - expr);
15373 	    }
15374 	}
15375 	vim_regfree(regmatch.regprog);
15376     }
15377 
15378 theend:
15379     vim_free(tofree);
15380     p_cpo = save_cpo;
15381 }
15382 
15383 /*
15384  * "match()" function
15385  */
15386     static void
15387 f_match(typval_T *argvars, typval_T *rettv)
15388 {
15389     find_some_match(argvars, rettv, 1);
15390 }
15391 
15392 /*
15393  * "matchadd()" function
15394  */
15395     static void
15396 f_matchadd(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
15397 {
15398 #ifdef FEAT_SEARCH_EXTRA
15399     char_u	buf[NUMBUFLEN];
15400     char_u	*grp = get_tv_string_buf_chk(&argvars[0], buf);	/* group */
15401     char_u	*pat = get_tv_string_buf_chk(&argvars[1], buf);	/* pattern */
15402     int		prio = 10;	/* default priority */
15403     int		id = -1;
15404     int		error = FALSE;
15405     char_u	*conceal_char = NULL;
15406 
15407     rettv->vval.v_number = -1;
15408 
15409     if (grp == NULL || pat == NULL)
15410 	return;
15411     if (argvars[2].v_type != VAR_UNKNOWN)
15412     {
15413 	prio = get_tv_number_chk(&argvars[2], &error);
15414 	if (argvars[3].v_type != VAR_UNKNOWN)
15415 	{
15416 	    id = get_tv_number_chk(&argvars[3], &error);
15417 	    if (argvars[4].v_type != VAR_UNKNOWN)
15418 	    {
15419 		if (argvars[4].v_type != VAR_DICT)
15420 		{
15421 		    EMSG(_(e_dictreq));
15422 		    return;
15423 		}
15424 		if (dict_find(argvars[4].vval.v_dict,
15425 					     (char_u *)"conceal", -1) != NULL)
15426 		    conceal_char = get_dict_string(argvars[4].vval.v_dict,
15427 						  (char_u *)"conceal", FALSE);
15428 	    }
15429 	}
15430     }
15431     if (error == TRUE)
15432 	return;
15433     if (id >= 1 && id <= 3)
15434     {
15435 	EMSGN("E798: ID is reserved for \":match\": %ld", id);
15436 	return;
15437     }
15438 
15439     rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL,
15440 								conceal_char);
15441 #endif
15442 }
15443 
15444 /*
15445  * "matchaddpos()" function
15446  */
15447     static void
15448 f_matchaddpos(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
15449 {
15450 #ifdef FEAT_SEARCH_EXTRA
15451     char_u	buf[NUMBUFLEN];
15452     char_u	*group;
15453     int		prio = 10;
15454     int		id = -1;
15455     int		error = FALSE;
15456     list_T	*l;
15457     char_u	*conceal_char = NULL;
15458 
15459     rettv->vval.v_number = -1;
15460 
15461     group = get_tv_string_buf_chk(&argvars[0], buf);
15462     if (group == NULL)
15463 	return;
15464 
15465     if (argvars[1].v_type != VAR_LIST)
15466     {
15467 	EMSG2(_(e_listarg), "matchaddpos()");
15468 	return;
15469     }
15470     l = argvars[1].vval.v_list;
15471     if (l == NULL)
15472 	return;
15473 
15474     if (argvars[2].v_type != VAR_UNKNOWN)
15475     {
15476 	prio = get_tv_number_chk(&argvars[2], &error);
15477 	if (argvars[3].v_type != VAR_UNKNOWN)
15478 	{
15479 	    id = get_tv_number_chk(&argvars[3], &error);
15480 	    if (argvars[4].v_type != VAR_UNKNOWN)
15481 	    {
15482 		if (argvars[4].v_type != VAR_DICT)
15483 		{
15484 		    EMSG(_(e_dictreq));
15485 		    return;
15486 		}
15487 		if (dict_find(argvars[4].vval.v_dict,
15488 					     (char_u *)"conceal", -1) != NULL)
15489 		    conceal_char = get_dict_string(argvars[4].vval.v_dict,
15490 						  (char_u *)"conceal", FALSE);
15491 	    }
15492 	}
15493     }
15494     if (error == TRUE)
15495 	return;
15496 
15497     /* id == 3 is ok because matchaddpos() is supposed to substitute :3match */
15498     if (id == 1 || id == 2)
15499     {
15500 	EMSGN("E798: ID is reserved for \":match\": %ld", id);
15501 	return;
15502     }
15503 
15504     rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l,
15505 								conceal_char);
15506 #endif
15507 }
15508 
15509 /*
15510  * "matcharg()" function
15511  */
15512     static void
15513 f_matcharg(typval_T *argvars UNUSED, typval_T *rettv)
15514 {
15515     if (rettv_list_alloc(rettv) == OK)
15516     {
15517 #ifdef FEAT_SEARCH_EXTRA
15518 	int	    id = get_tv_number(&argvars[0]);
15519 	matchitem_T *m;
15520 
15521 	if (id >= 1 && id <= 3)
15522 	{
15523 	    if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
15524 	    {
15525 		list_append_string(rettv->vval.v_list,
15526 						syn_id2name(m->hlg_id), -1);
15527 		list_append_string(rettv->vval.v_list, m->pattern, -1);
15528 	    }
15529 	    else
15530 	    {
15531 		list_append_string(rettv->vval.v_list, NULL, -1);
15532 		list_append_string(rettv->vval.v_list, NULL, -1);
15533 	    }
15534 	}
15535 #endif
15536     }
15537 }
15538 
15539 /*
15540  * "matchdelete()" function
15541  */
15542     static void
15543 f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
15544 {
15545 #ifdef FEAT_SEARCH_EXTRA
15546     rettv->vval.v_number = match_delete(curwin,
15547 				       (int)get_tv_number(&argvars[0]), TRUE);
15548 #endif
15549 }
15550 
15551 /*
15552  * "matchend()" function
15553  */
15554     static void
15555 f_matchend(typval_T *argvars, typval_T *rettv)
15556 {
15557     find_some_match(argvars, rettv, 0);
15558 }
15559 
15560 /*
15561  * "matchlist()" function
15562  */
15563     static void
15564 f_matchlist(typval_T *argvars, typval_T *rettv)
15565 {
15566     find_some_match(argvars, rettv, 3);
15567 }
15568 
15569 /*
15570  * "matchstr()" function
15571  */
15572     static void
15573 f_matchstr(typval_T *argvars, typval_T *rettv)
15574 {
15575     find_some_match(argvars, rettv, 2);
15576 }
15577 
15578 static void max_min(typval_T *argvars, typval_T *rettv, int domax);
15579 
15580     static void
15581 max_min(typval_T *argvars, typval_T *rettv, int domax)
15582 {
15583     long	n = 0;
15584     long	i;
15585     int		error = FALSE;
15586 
15587     if (argvars[0].v_type == VAR_LIST)
15588     {
15589 	list_T		*l;
15590 	listitem_T	*li;
15591 
15592 	l = argvars[0].vval.v_list;
15593 	if (l != NULL)
15594 	{
15595 	    li = l->lv_first;
15596 	    if (li != NULL)
15597 	    {
15598 		n = get_tv_number_chk(&li->li_tv, &error);
15599 		for (;;)
15600 		{
15601 		    li = li->li_next;
15602 		    if (li == NULL)
15603 			break;
15604 		    i = get_tv_number_chk(&li->li_tv, &error);
15605 		    if (domax ? i > n : i < n)
15606 			n = i;
15607 		}
15608 	    }
15609 	}
15610     }
15611     else if (argvars[0].v_type == VAR_DICT)
15612     {
15613 	dict_T		*d;
15614 	int		first = TRUE;
15615 	hashitem_T	*hi;
15616 	int		todo;
15617 
15618 	d = argvars[0].vval.v_dict;
15619 	if (d != NULL)
15620 	{
15621 	    todo = (int)d->dv_hashtab.ht_used;
15622 	    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
15623 	    {
15624 		if (!HASHITEM_EMPTY(hi))
15625 		{
15626 		    --todo;
15627 		    i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error);
15628 		    if (first)
15629 		    {
15630 			n = i;
15631 			first = FALSE;
15632 		    }
15633 		    else if (domax ? i > n : i < n)
15634 			n = i;
15635 		}
15636 	    }
15637 	}
15638     }
15639     else
15640 	EMSG(_(e_listdictarg));
15641     rettv->vval.v_number = error ? 0 : n;
15642 }
15643 
15644 /*
15645  * "max()" function
15646  */
15647     static void
15648 f_max(typval_T *argvars, typval_T *rettv)
15649 {
15650     max_min(argvars, rettv, TRUE);
15651 }
15652 
15653 /*
15654  * "min()" function
15655  */
15656     static void
15657 f_min(typval_T *argvars, typval_T *rettv)
15658 {
15659     max_min(argvars, rettv, FALSE);
15660 }
15661 
15662 static int mkdir_recurse(char_u *dir, int prot);
15663 
15664 /*
15665  * Create the directory in which "dir" is located, and higher levels when
15666  * needed.
15667  */
15668     static int
15669 mkdir_recurse(char_u *dir, int prot)
15670 {
15671     char_u	*p;
15672     char_u	*updir;
15673     int		r = FAIL;
15674 
15675     /* Get end of directory name in "dir".
15676      * We're done when it's "/" or "c:/". */
15677     p = gettail_sep(dir);
15678     if (p <= get_past_head(dir))
15679 	return OK;
15680 
15681     /* If the directory exists we're done.  Otherwise: create it.*/
15682     updir = vim_strnsave(dir, (int)(p - dir));
15683     if (updir == NULL)
15684 	return FAIL;
15685     if (mch_isdir(updir))
15686 	r = OK;
15687     else if (mkdir_recurse(updir, prot) == OK)
15688 	r = vim_mkdir_emsg(updir, prot);
15689     vim_free(updir);
15690     return r;
15691 }
15692 
15693 #ifdef vim_mkdir
15694 /*
15695  * "mkdir()" function
15696  */
15697     static void
15698 f_mkdir(typval_T *argvars, typval_T *rettv)
15699 {
15700     char_u	*dir;
15701     char_u	buf[NUMBUFLEN];
15702     int		prot = 0755;
15703 
15704     rettv->vval.v_number = FAIL;
15705     if (check_restricted() || check_secure())
15706 	return;
15707 
15708     dir = get_tv_string_buf(&argvars[0], buf);
15709     if (*dir == NUL)
15710 	rettv->vval.v_number = FAIL;
15711     else
15712     {
15713 	if (*gettail(dir) == NUL)
15714 	    /* remove trailing slashes */
15715 	    *gettail_sep(dir) = NUL;
15716 
15717 	if (argvars[1].v_type != VAR_UNKNOWN)
15718 	{
15719 	    if (argvars[2].v_type != VAR_UNKNOWN)
15720 		prot = get_tv_number_chk(&argvars[2], NULL);
15721 	    if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0)
15722 		mkdir_recurse(dir, prot);
15723 	}
15724 	rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot);
15725     }
15726 }
15727 #endif
15728 
15729 /*
15730  * "mode()" function
15731  */
15732     static void
15733 f_mode(typval_T *argvars, typval_T *rettv)
15734 {
15735     char_u	buf[3];
15736 
15737     buf[1] = NUL;
15738     buf[2] = NUL;
15739 
15740     if (VIsual_active)
15741     {
15742 	if (VIsual_select)
15743 	    buf[0] = VIsual_mode + 's' - 'v';
15744 	else
15745 	    buf[0] = VIsual_mode;
15746     }
15747     else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
15748 		|| State == CONFIRM)
15749     {
15750 	buf[0] = 'r';
15751 	if (State == ASKMORE)
15752 	    buf[1] = 'm';
15753 	else if (State == CONFIRM)
15754 	    buf[1] = '?';
15755     }
15756     else if (State == EXTERNCMD)
15757 	buf[0] = '!';
15758     else if (State & INSERT)
15759     {
15760 #ifdef FEAT_VREPLACE
15761 	if (State & VREPLACE_FLAG)
15762 	{
15763 	    buf[0] = 'R';
15764 	    buf[1] = 'v';
15765 	}
15766 	else
15767 #endif
15768 	if (State & REPLACE_FLAG)
15769 	    buf[0] = 'R';
15770 	else
15771 	    buf[0] = 'i';
15772     }
15773     else if (State & CMDLINE)
15774     {
15775 	buf[0] = 'c';
15776 	if (exmode_active)
15777 	    buf[1] = 'v';
15778     }
15779     else if (exmode_active)
15780     {
15781 	buf[0] = 'c';
15782 	buf[1] = 'e';
15783     }
15784     else
15785     {
15786 	buf[0] = 'n';
15787 	if (finish_op)
15788 	    buf[1] = 'o';
15789     }
15790 
15791     /* Clear out the minor mode when the argument is not a non-zero number or
15792      * non-empty string.  */
15793     if (!non_zero_arg(&argvars[0]))
15794 	buf[1] = NUL;
15795 
15796     rettv->vval.v_string = vim_strsave(buf);
15797     rettv->v_type = VAR_STRING;
15798 }
15799 
15800 #if defined(FEAT_MZSCHEME) || defined(PROTO)
15801 /*
15802  * "mzeval()" function
15803  */
15804     static void
15805 f_mzeval(typval_T *argvars, typval_T *rettv)
15806 {
15807     char_u	*str;
15808     char_u	buf[NUMBUFLEN];
15809 
15810     str = get_tv_string_buf(&argvars[0], buf);
15811     do_mzeval(str, rettv);
15812 }
15813 
15814     void
15815 mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv)
15816 {
15817     typval_T argvars[3];
15818 
15819     argvars[0].v_type = VAR_STRING;
15820     argvars[0].vval.v_string = name;
15821     copy_tv(args, &argvars[1]);
15822     argvars[2].v_type = VAR_UNKNOWN;
15823     f_call(argvars, rettv);
15824     clear_tv(&argvars[1]);
15825 }
15826 #endif
15827 
15828 /*
15829  * "nextnonblank()" function
15830  */
15831     static void
15832 f_nextnonblank(typval_T *argvars, typval_T *rettv)
15833 {
15834     linenr_T	lnum;
15835 
15836     for (lnum = get_tv_lnum(argvars); ; ++lnum)
15837     {
15838 	if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count)
15839 	{
15840 	    lnum = 0;
15841 	    break;
15842 	}
15843 	if (*skipwhite(ml_get(lnum)) != NUL)
15844 	    break;
15845     }
15846     rettv->vval.v_number = lnum;
15847 }
15848 
15849 /*
15850  * "nr2char()" function
15851  */
15852     static void
15853 f_nr2char(typval_T *argvars, typval_T *rettv)
15854 {
15855     char_u	buf[NUMBUFLEN];
15856 
15857 #ifdef FEAT_MBYTE
15858     if (has_mbyte)
15859     {
15860 	int	utf8 = 0;
15861 
15862 	if (argvars[1].v_type != VAR_UNKNOWN)
15863 	    utf8 = get_tv_number_chk(&argvars[1], NULL);
15864 	if (utf8)
15865 	    buf[(*utf_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
15866 	else
15867 	    buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
15868     }
15869     else
15870 #endif
15871     {
15872 	buf[0] = (char_u)get_tv_number(&argvars[0]);
15873 	buf[1] = NUL;
15874     }
15875     rettv->v_type = VAR_STRING;
15876     rettv->vval.v_string = vim_strsave(buf);
15877 }
15878 
15879 /*
15880  * "or(expr, expr)" function
15881  */
15882     static void
15883 f_or(typval_T *argvars, typval_T *rettv)
15884 {
15885     rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
15886 					| get_tv_number_chk(&argvars[1], NULL);
15887 }
15888 
15889 /*
15890  * "pathshorten()" function
15891  */
15892     static void
15893 f_pathshorten(typval_T *argvars, typval_T *rettv)
15894 {
15895     char_u	*p;
15896 
15897     rettv->v_type = VAR_STRING;
15898     p = get_tv_string_chk(&argvars[0]);
15899     if (p == NULL)
15900 	rettv->vval.v_string = NULL;
15901     else
15902     {
15903 	p = vim_strsave(p);
15904 	rettv->vval.v_string = p;
15905 	if (p != NULL)
15906 	    shorten_dir(p);
15907     }
15908 }
15909 
15910 #ifdef FEAT_PERL
15911 /*
15912  * "perleval()" function
15913  */
15914     static void
15915 f_perleval(typval_T *argvars, typval_T *rettv)
15916 {
15917     char_u	*str;
15918     char_u	buf[NUMBUFLEN];
15919 
15920     str = get_tv_string_buf(&argvars[0], buf);
15921     do_perleval(str, rettv);
15922 }
15923 #endif
15924 
15925 #ifdef FEAT_FLOAT
15926 /*
15927  * "pow()" function
15928  */
15929     static void
15930 f_pow(typval_T *argvars, typval_T *rettv)
15931 {
15932     float_T	fx = 0.0, fy = 0.0;
15933 
15934     rettv->v_type = VAR_FLOAT;
15935     if (get_float_arg(argvars, &fx) == OK
15936 				     && get_float_arg(&argvars[1], &fy) == OK)
15937 	rettv->vval.v_float = pow(fx, fy);
15938     else
15939 	rettv->vval.v_float = 0.0;
15940 }
15941 #endif
15942 
15943 /*
15944  * "prevnonblank()" function
15945  */
15946     static void
15947 f_prevnonblank(typval_T *argvars, typval_T *rettv)
15948 {
15949     linenr_T	lnum;
15950 
15951     lnum = get_tv_lnum(argvars);
15952     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
15953 	lnum = 0;
15954     else
15955 	while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
15956 	    --lnum;
15957     rettv->vval.v_number = lnum;
15958 }
15959 
15960 /* This dummy va_list is here because:
15961  * - passing a NULL pointer doesn't work when va_list isn't a pointer
15962  * - locally in the function results in a "used before set" warning
15963  * - using va_start() to initialize it gives "function with fixed args" error */
15964 static va_list	ap;
15965 
15966 /*
15967  * "printf()" function
15968  */
15969     static void
15970 f_printf(typval_T *argvars, typval_T *rettv)
15971 {
15972     char_u	buf[NUMBUFLEN];
15973     int		len;
15974     char_u	*s;
15975     int		saved_did_emsg = did_emsg;
15976     char	*fmt;
15977 
15978     rettv->v_type = VAR_STRING;
15979     rettv->vval.v_string = NULL;
15980 
15981     /* Get the required length, allocate the buffer and do it for real. */
15982     did_emsg = FALSE;
15983     fmt = (char *)get_tv_string_buf(&argvars[0], buf);
15984     len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1);
15985     if (!did_emsg)
15986     {
15987 	s = alloc(len + 1);
15988 	if (s != NULL)
15989 	{
15990 	    rettv->vval.v_string = s;
15991 	    (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1);
15992 	}
15993     }
15994     did_emsg |= saved_did_emsg;
15995 }
15996 
15997 /*
15998  * "pumvisible()" function
15999  */
16000     static void
16001 f_pumvisible(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
16002 {
16003 #ifdef FEAT_INS_EXPAND
16004     if (pum_visible())
16005 	rettv->vval.v_number = 1;
16006 #endif
16007 }
16008 
16009 #ifdef FEAT_PYTHON3
16010 /*
16011  * "py3eval()" function
16012  */
16013     static void
16014 f_py3eval(typval_T *argvars, typval_T *rettv)
16015 {
16016     char_u	*str;
16017     char_u	buf[NUMBUFLEN];
16018 
16019     str = get_tv_string_buf(&argvars[0], buf);
16020     do_py3eval(str, rettv);
16021 }
16022 #endif
16023 
16024 #ifdef FEAT_PYTHON
16025 /*
16026  * "pyeval()" function
16027  */
16028     static void
16029 f_pyeval(typval_T *argvars, typval_T *rettv)
16030 {
16031     char_u	*str;
16032     char_u	buf[NUMBUFLEN];
16033 
16034     str = get_tv_string_buf(&argvars[0], buf);
16035     do_pyeval(str, rettv);
16036 }
16037 #endif
16038 
16039 /*
16040  * "range()" function
16041  */
16042     static void
16043 f_range(typval_T *argvars, typval_T *rettv)
16044 {
16045     long	start;
16046     long	end;
16047     long	stride = 1;
16048     long	i;
16049     int		error = FALSE;
16050 
16051     start = get_tv_number_chk(&argvars[0], &error);
16052     if (argvars[1].v_type == VAR_UNKNOWN)
16053     {
16054 	end = start - 1;
16055 	start = 0;
16056     }
16057     else
16058     {
16059 	end = get_tv_number_chk(&argvars[1], &error);
16060 	if (argvars[2].v_type != VAR_UNKNOWN)
16061 	    stride = get_tv_number_chk(&argvars[2], &error);
16062     }
16063 
16064     if (error)
16065 	return;		/* type error; errmsg already given */
16066     if (stride == 0)
16067 	EMSG(_("E726: Stride is zero"));
16068     else if (stride > 0 ? end + 1 < start : end - 1 > start)
16069 	EMSG(_("E727: Start past end"));
16070     else
16071     {
16072 	if (rettv_list_alloc(rettv) == OK)
16073 	    for (i = start; stride > 0 ? i <= end : i >= end; i += stride)
16074 		if (list_append_number(rettv->vval.v_list,
16075 						      (varnumber_T)i) == FAIL)
16076 		    break;
16077     }
16078 }
16079 
16080 /*
16081  * "readfile()" function
16082  */
16083     static void
16084 f_readfile(typval_T *argvars, typval_T *rettv)
16085 {
16086     int		binary = FALSE;
16087     int		failed = FALSE;
16088     char_u	*fname;
16089     FILE	*fd;
16090     char_u	buf[(IOSIZE/256)*256];	/* rounded to avoid odd + 1 */
16091     int		io_size = sizeof(buf);
16092     int		readlen;		/* size of last fread() */
16093     char_u	*prev	 = NULL;	/* previously read bytes, if any */
16094     long	prevlen  = 0;		/* length of data in prev */
16095     long	prevsize = 0;		/* size of prev buffer */
16096     long	maxline  = MAXLNUM;
16097     long	cnt	 = 0;
16098     char_u	*p;			/* position in buf */
16099     char_u	*start;			/* start of current line */
16100 
16101     if (argvars[1].v_type != VAR_UNKNOWN)
16102     {
16103 	if (STRCMP(get_tv_string(&argvars[1]), "b") == 0)
16104 	    binary = TRUE;
16105 	if (argvars[2].v_type != VAR_UNKNOWN)
16106 	    maxline = get_tv_number(&argvars[2]);
16107     }
16108 
16109     if (rettv_list_alloc(rettv) == FAIL)
16110 	return;
16111 
16112     /* Always open the file in binary mode, library functions have a mind of
16113      * their own about CR-LF conversion. */
16114     fname = get_tv_string(&argvars[0]);
16115     if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL)
16116     {
16117 	EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname);
16118 	return;
16119     }
16120 
16121     while (cnt < maxline || maxline < 0)
16122     {
16123 	readlen = (int)fread(buf, 1, io_size, fd);
16124 
16125 	/* This for loop processes what was read, but is also entered at end
16126 	 * of file so that either:
16127 	 * - an incomplete line gets written
16128 	 * - a "binary" file gets an empty line at the end if it ends in a
16129 	 *   newline.  */
16130 	for (p = buf, start = buf;
16131 		p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary));
16132 		++p)
16133 	{
16134 	    if (*p == '\n' || readlen <= 0)
16135 	    {
16136 		listitem_T  *li;
16137 		char_u	    *s	= NULL;
16138 		long_u	    len = p - start;
16139 
16140 		/* Finished a line.  Remove CRs before NL. */
16141 		if (readlen > 0 && !binary)
16142 		{
16143 		    while (len > 0 && start[len - 1] == '\r')
16144 			--len;
16145 		    /* removal may cross back to the "prev" string */
16146 		    if (len == 0)
16147 			while (prevlen > 0 && prev[prevlen - 1] == '\r')
16148 			    --prevlen;
16149 		}
16150 		if (prevlen == 0)
16151 		    s = vim_strnsave(start, (int)len);
16152 		else
16153 		{
16154 		    /* Change "prev" buffer to be the right size.  This way
16155 		     * the bytes are only copied once, and very long lines are
16156 		     * allocated only once.  */
16157 		    if ((s = vim_realloc(prev, prevlen + len + 1)) != NULL)
16158 		    {
16159 			mch_memmove(s + prevlen, start, len);
16160 			s[prevlen + len] = NUL;
16161 			prev = NULL; /* the list will own the string */
16162 			prevlen = prevsize = 0;
16163 		    }
16164 		}
16165 		if (s == NULL)
16166 		{
16167 		    do_outofmem_msg((long_u) prevlen + len + 1);
16168 		    failed = TRUE;
16169 		    break;
16170 		}
16171 
16172 		if ((li = listitem_alloc()) == NULL)
16173 		{
16174 		    vim_free(s);
16175 		    failed = TRUE;
16176 		    break;
16177 		}
16178 		li->li_tv.v_type = VAR_STRING;
16179 		li->li_tv.v_lock = 0;
16180 		li->li_tv.vval.v_string = s;
16181 		list_append(rettv->vval.v_list, li);
16182 
16183 		start = p + 1; /* step over newline */
16184 		if ((++cnt >= maxline && maxline >= 0) || readlen <= 0)
16185 		    break;
16186 	    }
16187 	    else if (*p == NUL)
16188 		*p = '\n';
16189 #ifdef FEAT_MBYTE
16190 	    /* Check for utf8 "bom"; U+FEFF is encoded as EF BB BF.  Do this
16191 	     * when finding the BF and check the previous two bytes. */
16192 	    else if (*p == 0xbf && enc_utf8 && !binary)
16193 	    {
16194 		/* Find the two bytes before the 0xbf.	If p is at buf, or buf
16195 		 * + 1, these may be in the "prev" string. */
16196 		char_u back1 = p >= buf + 1 ? p[-1]
16197 				     : prevlen >= 1 ? prev[prevlen - 1] : NUL;
16198 		char_u back2 = p >= buf + 2 ? p[-2]
16199 			  : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1]
16200 			  : prevlen >= 2 ? prev[prevlen - 2] : NUL;
16201 
16202 		if (back2 == 0xef && back1 == 0xbb)
16203 		{
16204 		    char_u *dest = p - 2;
16205 
16206 		    /* Usually a BOM is at the beginning of a file, and so at
16207 		     * the beginning of a line; then we can just step over it.
16208 		     */
16209 		    if (start == dest)
16210 			start = p + 1;
16211 		    else
16212 		    {
16213 			/* have to shuffle buf to close gap */
16214 			int adjust_prevlen = 0;
16215 
16216 			if (dest < buf)
16217 			{
16218 			    adjust_prevlen = (int)(buf - dest); /* must be 1 or 2 */
16219 			    dest = buf;
16220 			}
16221 			if (readlen > p - buf + 1)
16222 			    mch_memmove(dest, p + 1, readlen - (p - buf) - 1);
16223 			readlen -= 3 - adjust_prevlen;
16224 			prevlen -= adjust_prevlen;
16225 			p = dest - 1;
16226 		    }
16227 		}
16228 	    }
16229 #endif
16230 	} /* for */
16231 
16232 	if (failed || (cnt >= maxline && maxline >= 0) || readlen <= 0)
16233 	    break;
16234 	if (start < p)
16235 	{
16236 	    /* There's part of a line in buf, store it in "prev". */
16237 	    if (p - start + prevlen >= prevsize)
16238 	    {
16239 		/* need bigger "prev" buffer */
16240 		char_u *newprev;
16241 
16242 		/* A common use case is ordinary text files and "prev" gets a
16243 		 * fragment of a line, so the first allocation is made
16244 		 * small, to avoid repeatedly 'allocing' large and
16245 		 * 'reallocing' small. */
16246 		if (prevsize == 0)
16247 		    prevsize = (long)(p - start);
16248 		else
16249 		{
16250 		    long grow50pc = (prevsize * 3) / 2;
16251 		    long growmin  = (long)((p - start) * 2 + prevlen);
16252 		    prevsize = grow50pc > growmin ? grow50pc : growmin;
16253 		}
16254 		newprev = prev == NULL ? alloc(prevsize)
16255 						: vim_realloc(prev, prevsize);
16256 		if (newprev == NULL)
16257 		{
16258 		    do_outofmem_msg((long_u)prevsize);
16259 		    failed = TRUE;
16260 		    break;
16261 		}
16262 		prev = newprev;
16263 	    }
16264 	    /* Add the line part to end of "prev". */
16265 	    mch_memmove(prev + prevlen, start, p - start);
16266 	    prevlen += (long)(p - start);
16267 	}
16268     } /* while */
16269 
16270     /*
16271      * For a negative line count use only the lines at the end of the file,
16272      * free the rest.
16273      */
16274     if (!failed && maxline < 0)
16275 	while (cnt > -maxline)
16276 	{
16277 	    listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first);
16278 	    --cnt;
16279 	}
16280 
16281     if (failed)
16282     {
16283 	list_free(rettv->vval.v_list, TRUE);
16284 	/* readfile doc says an empty list is returned on error */
16285 	rettv->vval.v_list = list_alloc();
16286     }
16287 
16288     vim_free(prev);
16289     fclose(fd);
16290 }
16291 
16292 #if defined(FEAT_RELTIME)
16293 static int list2proftime(typval_T *arg, proftime_T *tm);
16294 
16295 /*
16296  * Convert a List to proftime_T.
16297  * Return FAIL when there is something wrong.
16298  */
16299     static int
16300 list2proftime(typval_T *arg, proftime_T *tm)
16301 {
16302     long	n1, n2;
16303     int	error = FALSE;
16304 
16305     if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL
16306 					     || arg->vval.v_list->lv_len != 2)
16307 	return FAIL;
16308     n1 = list_find_nr(arg->vval.v_list, 0L, &error);
16309     n2 = list_find_nr(arg->vval.v_list, 1L, &error);
16310 # ifdef WIN3264
16311     tm->HighPart = n1;
16312     tm->LowPart = n2;
16313 # else
16314     tm->tv_sec = n1;
16315     tm->tv_usec = n2;
16316 # endif
16317     return error ? FAIL : OK;
16318 }
16319 #endif /* FEAT_RELTIME */
16320 
16321 /*
16322  * "reltime()" function
16323  */
16324     static void
16325 f_reltime(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
16326 {
16327 #ifdef FEAT_RELTIME
16328     proftime_T	res;
16329     proftime_T	start;
16330 
16331     if (argvars[0].v_type == VAR_UNKNOWN)
16332     {
16333 	/* No arguments: get current time. */
16334 	profile_start(&res);
16335     }
16336     else if (argvars[1].v_type == VAR_UNKNOWN)
16337     {
16338 	if (list2proftime(&argvars[0], &res) == FAIL)
16339 	    return;
16340 	profile_end(&res);
16341     }
16342     else
16343     {
16344 	/* Two arguments: compute the difference. */
16345 	if (list2proftime(&argvars[0], &start) == FAIL
16346 		|| list2proftime(&argvars[1], &res) == FAIL)
16347 	    return;
16348 	profile_sub(&res, &start);
16349     }
16350 
16351     if (rettv_list_alloc(rettv) == OK)
16352     {
16353 	long	n1, n2;
16354 
16355 # ifdef WIN3264
16356 	n1 = res.HighPart;
16357 	n2 = res.LowPart;
16358 # else
16359 	n1 = res.tv_sec;
16360 	n2 = res.tv_usec;
16361 # endif
16362 	list_append_number(rettv->vval.v_list, (varnumber_T)n1);
16363 	list_append_number(rettv->vval.v_list, (varnumber_T)n2);
16364     }
16365 #endif
16366 }
16367 
16368 #ifdef FEAT_FLOAT
16369 /*
16370  * "reltimefloat()" function
16371  */
16372     static void
16373 f_reltimefloat(typval_T *argvars UNUSED, typval_T *rettv)
16374 {
16375 # ifdef FEAT_RELTIME
16376     proftime_T	tm;
16377 # endif
16378 
16379     rettv->v_type = VAR_FLOAT;
16380     rettv->vval.v_float = 0;
16381 # ifdef FEAT_RELTIME
16382     if (list2proftime(&argvars[0], &tm) == OK)
16383 	rettv->vval.v_float = profile_float(&tm);
16384 # endif
16385 }
16386 #endif
16387 
16388 /*
16389  * "reltimestr()" function
16390  */
16391     static void
16392 f_reltimestr(typval_T *argvars UNUSED, typval_T *rettv)
16393 {
16394 #ifdef FEAT_RELTIME
16395     proftime_T	tm;
16396 #endif
16397 
16398     rettv->v_type = VAR_STRING;
16399     rettv->vval.v_string = NULL;
16400 #ifdef FEAT_RELTIME
16401     if (list2proftime(&argvars[0], &tm) == OK)
16402 	rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm));
16403 #endif
16404 }
16405 
16406 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
16407 static void make_connection(void);
16408 static int check_connection(void);
16409 
16410     static void
16411 make_connection(void)
16412 {
16413     if (X_DISPLAY == NULL
16414 # ifdef FEAT_GUI
16415 	    && !gui.in_use
16416 # endif
16417 	    )
16418     {
16419 	x_force_connect = TRUE;
16420 	setup_term_clip();
16421 	x_force_connect = FALSE;
16422     }
16423 }
16424 
16425     static int
16426 check_connection(void)
16427 {
16428     make_connection();
16429     if (X_DISPLAY == NULL)
16430     {
16431 	EMSG(_("E240: No connection to Vim server"));
16432 	return FAIL;
16433     }
16434     return OK;
16435 }
16436 #endif
16437 
16438 #ifdef FEAT_CLIENTSERVER
16439 static void remote_common(typval_T *argvars, typval_T *rettv, int expr);
16440 
16441     static void
16442 remote_common(typval_T *argvars, typval_T *rettv, int expr)
16443 {
16444     char_u	*server_name;
16445     char_u	*keys;
16446     char_u	*r = NULL;
16447     char_u	buf[NUMBUFLEN];
16448 # ifdef WIN32
16449     HWND	w;
16450 # else
16451     Window	w;
16452 # endif
16453 
16454     if (check_restricted() || check_secure())
16455 	return;
16456 
16457 # ifdef FEAT_X11
16458     if (check_connection() == FAIL)
16459 	return;
16460 # endif
16461 
16462     server_name = get_tv_string_chk(&argvars[0]);
16463     if (server_name == NULL)
16464 	return;		/* type error; errmsg already given */
16465     keys = get_tv_string_buf(&argvars[1], buf);
16466 # ifdef WIN32
16467     if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0)
16468 # else
16469     if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE)
16470 									  < 0)
16471 # endif
16472     {
16473 	if (r != NULL)
16474 	    EMSG(r);		/* sending worked but evaluation failed */
16475 	else
16476 	    EMSG2(_("E241: Unable to send to %s"), server_name);
16477 	return;
16478     }
16479 
16480     rettv->vval.v_string = r;
16481 
16482     if (argvars[2].v_type != VAR_UNKNOWN)
16483     {
16484 	dictitem_T	v;
16485 	char_u		str[30];
16486 	char_u		*idvar;
16487 
16488 	sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w);
16489 	v.di_tv.v_type = VAR_STRING;
16490 	v.di_tv.vval.v_string = vim_strsave(str);
16491 	idvar = get_tv_string_chk(&argvars[2]);
16492 	if (idvar != NULL)
16493 	    set_var(idvar, &v.di_tv, FALSE);
16494 	vim_free(v.di_tv.vval.v_string);
16495     }
16496 }
16497 #endif
16498 
16499 /*
16500  * "remote_expr()" function
16501  */
16502     static void
16503 f_remote_expr(typval_T *argvars UNUSED, typval_T *rettv)
16504 {
16505     rettv->v_type = VAR_STRING;
16506     rettv->vval.v_string = NULL;
16507 #ifdef FEAT_CLIENTSERVER
16508     remote_common(argvars, rettv, TRUE);
16509 #endif
16510 }
16511 
16512 /*
16513  * "remote_foreground()" function
16514  */
16515     static void
16516 f_remote_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
16517 {
16518 #ifdef FEAT_CLIENTSERVER
16519 # ifdef WIN32
16520     /* On Win32 it's done in this application. */
16521     {
16522 	char_u	*server_name = get_tv_string_chk(&argvars[0]);
16523 
16524 	if (server_name != NULL)
16525 	    serverForeground(server_name);
16526     }
16527 # else
16528     /* Send a foreground() expression to the server. */
16529     argvars[1].v_type = VAR_STRING;
16530     argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()");
16531     argvars[2].v_type = VAR_UNKNOWN;
16532     remote_common(argvars, rettv, TRUE);
16533     vim_free(argvars[1].vval.v_string);
16534 # endif
16535 #endif
16536 }
16537 
16538     static void
16539 f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv)
16540 {
16541 #ifdef FEAT_CLIENTSERVER
16542     dictitem_T	v;
16543     char_u	*s = NULL;
16544 # ifdef WIN32
16545     long_u	n = 0;
16546 # endif
16547     char_u	*serverid;
16548 
16549     if (check_restricted() || check_secure())
16550     {
16551 	rettv->vval.v_number = -1;
16552 	return;
16553     }
16554     serverid = get_tv_string_chk(&argvars[0]);
16555     if (serverid == NULL)
16556     {
16557 	rettv->vval.v_number = -1;
16558 	return;		/* type error; errmsg already given */
16559     }
16560 # ifdef WIN32
16561     sscanf((const char *)serverid, SCANF_HEX_LONG_U, &n);
16562     if (n == 0)
16563 	rettv->vval.v_number = -1;
16564     else
16565     {
16566 	s = serverGetReply((HWND)n, FALSE, FALSE, FALSE);
16567 	rettv->vval.v_number = (s != NULL);
16568     }
16569 # else
16570     if (check_connection() == FAIL)
16571 	return;
16572 
16573     rettv->vval.v_number = serverPeekReply(X_DISPLAY,
16574 						serverStrToWin(serverid), &s);
16575 # endif
16576 
16577     if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0)
16578     {
16579 	char_u		*retvar;
16580 
16581 	v.di_tv.v_type = VAR_STRING;
16582 	v.di_tv.vval.v_string = vim_strsave(s);
16583 	retvar = get_tv_string_chk(&argvars[1]);
16584 	if (retvar != NULL)
16585 	    set_var(retvar, &v.di_tv, FALSE);
16586 	vim_free(v.di_tv.vval.v_string);
16587     }
16588 #else
16589     rettv->vval.v_number = -1;
16590 #endif
16591 }
16592 
16593     static void
16594 f_remote_read(typval_T *argvars UNUSED, typval_T *rettv)
16595 {
16596     char_u	*r = NULL;
16597 
16598 #ifdef FEAT_CLIENTSERVER
16599     char_u	*serverid = get_tv_string_chk(&argvars[0]);
16600 
16601     if (serverid != NULL && !check_restricted() && !check_secure())
16602     {
16603 # ifdef WIN32
16604 	/* The server's HWND is encoded in the 'id' parameter */
16605 	long_u		n = 0;
16606 
16607 	sscanf((char *)serverid, SCANF_HEX_LONG_U, &n);
16608 	if (n != 0)
16609 	    r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
16610 	if (r == NULL)
16611 # else
16612 	if (check_connection() == FAIL || serverReadReply(X_DISPLAY,
16613 		serverStrToWin(serverid), &r, FALSE) < 0)
16614 # endif
16615 	    EMSG(_("E277: Unable to read a server reply"));
16616     }
16617 #endif
16618     rettv->v_type = VAR_STRING;
16619     rettv->vval.v_string = r;
16620 }
16621 
16622 /*
16623  * "remote_send()" function
16624  */
16625     static void
16626 f_remote_send(typval_T *argvars UNUSED, typval_T *rettv)
16627 {
16628     rettv->v_type = VAR_STRING;
16629     rettv->vval.v_string = NULL;
16630 #ifdef FEAT_CLIENTSERVER
16631     remote_common(argvars, rettv, FALSE);
16632 #endif
16633 }
16634 
16635 /*
16636  * "remove()" function
16637  */
16638     static void
16639 f_remove(typval_T *argvars, typval_T *rettv)
16640 {
16641     list_T	*l;
16642     listitem_T	*item, *item2;
16643     listitem_T	*li;
16644     long	idx;
16645     long	end;
16646     char_u	*key;
16647     dict_T	*d;
16648     dictitem_T	*di;
16649     char_u	*arg_errmsg = (char_u *)N_("remove() argument");
16650 
16651     if (argvars[0].v_type == VAR_DICT)
16652     {
16653 	if (argvars[2].v_type != VAR_UNKNOWN)
16654 	    EMSG2(_(e_toomanyarg), "remove()");
16655 	else if ((d = argvars[0].vval.v_dict) != NULL
16656 		&& !tv_check_lock(d->dv_lock, arg_errmsg, TRUE))
16657 	{
16658 	    key = get_tv_string_chk(&argvars[1]);
16659 	    if (key != NULL)
16660 	    {
16661 		di = dict_find(d, key, -1);
16662 		if (di == NULL)
16663 		    EMSG2(_(e_dictkey), key);
16664 		else if (!var_check_fixed(di->di_flags, arg_errmsg, TRUE)
16665 			    && !var_check_ro(di->di_flags, arg_errmsg, TRUE))
16666 		{
16667 		    *rettv = di->di_tv;
16668 		    init_tv(&di->di_tv);
16669 		    dictitem_remove(d, di);
16670 		}
16671 	    }
16672 	}
16673     }
16674     else if (argvars[0].v_type != VAR_LIST)
16675 	EMSG2(_(e_listdictarg), "remove()");
16676     else if ((l = argvars[0].vval.v_list) != NULL
16677 	    && !tv_check_lock(l->lv_lock, arg_errmsg, TRUE))
16678     {
16679 	int	    error = FALSE;
16680 
16681 	idx = get_tv_number_chk(&argvars[1], &error);
16682 	if (error)
16683 	    ;		/* type error: do nothing, errmsg already given */
16684 	else if ((item = list_find(l, idx)) == NULL)
16685 	    EMSGN(_(e_listidx), idx);
16686 	else
16687 	{
16688 	    if (argvars[2].v_type == VAR_UNKNOWN)
16689 	    {
16690 		/* Remove one item, return its value. */
16691 		vimlist_remove(l, item, item);
16692 		*rettv = item->li_tv;
16693 		vim_free(item);
16694 	    }
16695 	    else
16696 	    {
16697 		/* Remove range of items, return list with values. */
16698 		end = get_tv_number_chk(&argvars[2], &error);
16699 		if (error)
16700 		    ;		/* type error: do nothing */
16701 		else if ((item2 = list_find(l, end)) == NULL)
16702 		    EMSGN(_(e_listidx), end);
16703 		else
16704 		{
16705 		    int	    cnt = 0;
16706 
16707 		    for (li = item; li != NULL; li = li->li_next)
16708 		    {
16709 			++cnt;
16710 			if (li == item2)
16711 			    break;
16712 		    }
16713 		    if (li == NULL)  /* didn't find "item2" after "item" */
16714 			EMSG(_(e_invrange));
16715 		    else
16716 		    {
16717 			vimlist_remove(l, item, item2);
16718 			if (rettv_list_alloc(rettv) == OK)
16719 			{
16720 			    l = rettv->vval.v_list;
16721 			    l->lv_first = item;
16722 			    l->lv_last = item2;
16723 			    item->li_prev = NULL;
16724 			    item2->li_next = NULL;
16725 			    l->lv_len = cnt;
16726 			}
16727 		    }
16728 		}
16729 	    }
16730 	}
16731     }
16732 }
16733 
16734 /*
16735  * "rename({from}, {to})" function
16736  */
16737     static void
16738 f_rename(typval_T *argvars, typval_T *rettv)
16739 {
16740     char_u	buf[NUMBUFLEN];
16741 
16742     if (check_restricted() || check_secure())
16743 	rettv->vval.v_number = -1;
16744     else
16745 	rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]),
16746 				      get_tv_string_buf(&argvars[1], buf));
16747 }
16748 
16749 /*
16750  * "repeat()" function
16751  */
16752     static void
16753 f_repeat(typval_T *argvars, typval_T *rettv)
16754 {
16755     char_u	*p;
16756     int		n;
16757     int		slen;
16758     int		len;
16759     char_u	*r;
16760     int		i;
16761 
16762     n = get_tv_number(&argvars[1]);
16763     if (argvars[0].v_type == VAR_LIST)
16764     {
16765 	if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL)
16766 	    while (n-- > 0)
16767 		if (list_extend(rettv->vval.v_list,
16768 					argvars[0].vval.v_list, NULL) == FAIL)
16769 		    break;
16770     }
16771     else
16772     {
16773 	p = get_tv_string(&argvars[0]);
16774 	rettv->v_type = VAR_STRING;
16775 	rettv->vval.v_string = NULL;
16776 
16777 	slen = (int)STRLEN(p);
16778 	len = slen * n;
16779 	if (len <= 0)
16780 	    return;
16781 
16782 	r = alloc(len + 1);
16783 	if (r != NULL)
16784 	{
16785 	    for (i = 0; i < n; i++)
16786 		mch_memmove(r + i * slen, p, (size_t)slen);
16787 	    r[len] = NUL;
16788 	}
16789 
16790 	rettv->vval.v_string = r;
16791     }
16792 }
16793 
16794 /*
16795  * "resolve()" function
16796  */
16797     static void
16798 f_resolve(typval_T *argvars, typval_T *rettv)
16799 {
16800     char_u	*p;
16801 #ifdef HAVE_READLINK
16802     char_u	*buf = NULL;
16803 #endif
16804 
16805     p = get_tv_string(&argvars[0]);
16806 #ifdef FEAT_SHORTCUT
16807     {
16808 	char_u	*v = NULL;
16809 
16810 	v = mch_resolve_shortcut(p);
16811 	if (v != NULL)
16812 	    rettv->vval.v_string = v;
16813 	else
16814 	    rettv->vval.v_string = vim_strsave(p);
16815     }
16816 #else
16817 # ifdef HAVE_READLINK
16818     {
16819 	char_u	*cpy;
16820 	int	len;
16821 	char_u	*remain = NULL;
16822 	char_u	*q;
16823 	int	is_relative_to_current = FALSE;
16824 	int	has_trailing_pathsep = FALSE;
16825 	int	limit = 100;
16826 
16827 	p = vim_strsave(p);
16828 
16829 	if (p[0] == '.' && (vim_ispathsep(p[1])
16830 				   || (p[1] == '.' && (vim_ispathsep(p[2])))))
16831 	    is_relative_to_current = TRUE;
16832 
16833 	len = STRLEN(p);
16834 	if (len > 0 && after_pathsep(p, p + len))
16835 	{
16836 	    has_trailing_pathsep = TRUE;
16837 	    p[len - 1] = NUL; /* the trailing slash breaks readlink() */
16838 	}
16839 
16840 	q = getnextcomp(p);
16841 	if (*q != NUL)
16842 	{
16843 	    /* Separate the first path component in "p", and keep the
16844 	     * remainder (beginning with the path separator). */
16845 	    remain = vim_strsave(q - 1);
16846 	    q[-1] = NUL;
16847 	}
16848 
16849 	buf = alloc(MAXPATHL + 1);
16850 	if (buf == NULL)
16851 	    goto fail;
16852 
16853 	for (;;)
16854 	{
16855 	    for (;;)
16856 	    {
16857 		len = readlink((char *)p, (char *)buf, MAXPATHL);
16858 		if (len <= 0)
16859 		    break;
16860 		buf[len] = NUL;
16861 
16862 		if (limit-- == 0)
16863 		{
16864 		    vim_free(p);
16865 		    vim_free(remain);
16866 		    EMSG(_("E655: Too many symbolic links (cycle?)"));
16867 		    rettv->vval.v_string = NULL;
16868 		    goto fail;
16869 		}
16870 
16871 		/* Ensure that the result will have a trailing path separator
16872 		 * if the argument has one. */
16873 		if (remain == NULL && has_trailing_pathsep)
16874 		    add_pathsep(buf);
16875 
16876 		/* Separate the first path component in the link value and
16877 		 * concatenate the remainders. */
16878 		q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf);
16879 		if (*q != NUL)
16880 		{
16881 		    if (remain == NULL)
16882 			remain = vim_strsave(q - 1);
16883 		    else
16884 		    {
16885 			cpy = concat_str(q - 1, remain);
16886 			if (cpy != NULL)
16887 			{
16888 			    vim_free(remain);
16889 			    remain = cpy;
16890 			}
16891 		    }
16892 		    q[-1] = NUL;
16893 		}
16894 
16895 		q = gettail(p);
16896 		if (q > p && *q == NUL)
16897 		{
16898 		    /* Ignore trailing path separator. */
16899 		    q[-1] = NUL;
16900 		    q = gettail(p);
16901 		}
16902 		if (q > p && !mch_isFullName(buf))
16903 		{
16904 		    /* symlink is relative to directory of argument */
16905 		    cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
16906 		    if (cpy != NULL)
16907 		    {
16908 			STRCPY(cpy, p);
16909 			STRCPY(gettail(cpy), buf);
16910 			vim_free(p);
16911 			p = cpy;
16912 		    }
16913 		}
16914 		else
16915 		{
16916 		    vim_free(p);
16917 		    p = vim_strsave(buf);
16918 		}
16919 	    }
16920 
16921 	    if (remain == NULL)
16922 		break;
16923 
16924 	    /* Append the first path component of "remain" to "p". */
16925 	    q = getnextcomp(remain + 1);
16926 	    len = q - remain - (*q != NUL);
16927 	    cpy = vim_strnsave(p, STRLEN(p) + len);
16928 	    if (cpy != NULL)
16929 	    {
16930 		STRNCAT(cpy, remain, len);
16931 		vim_free(p);
16932 		p = cpy;
16933 	    }
16934 	    /* Shorten "remain". */
16935 	    if (*q != NUL)
16936 		STRMOVE(remain, q - 1);
16937 	    else
16938 	    {
16939 		vim_free(remain);
16940 		remain = NULL;
16941 	    }
16942 	}
16943 
16944 	/* If the result is a relative path name, make it explicitly relative to
16945 	 * the current directory if and only if the argument had this form. */
16946 	if (!vim_ispathsep(*p))
16947 	{
16948 	    if (is_relative_to_current
16949 		    && *p != NUL
16950 		    && !(p[0] == '.'
16951 			&& (p[1] == NUL
16952 			    || vim_ispathsep(p[1])
16953 			    || (p[1] == '.'
16954 				&& (p[2] == NUL
16955 				    || vim_ispathsep(p[2]))))))
16956 	    {
16957 		/* Prepend "./". */
16958 		cpy = concat_str((char_u *)"./", p);
16959 		if (cpy != NULL)
16960 		{
16961 		    vim_free(p);
16962 		    p = cpy;
16963 		}
16964 	    }
16965 	    else if (!is_relative_to_current)
16966 	    {
16967 		/* Strip leading "./". */
16968 		q = p;
16969 		while (q[0] == '.' && vim_ispathsep(q[1]))
16970 		    q += 2;
16971 		if (q > p)
16972 		    STRMOVE(p, p + 2);
16973 	    }
16974 	}
16975 
16976 	/* Ensure that the result will have no trailing path separator
16977 	 * if the argument had none.  But keep "/" or "//". */
16978 	if (!has_trailing_pathsep)
16979 	{
16980 	    q = p + STRLEN(p);
16981 	    if (after_pathsep(p, q))
16982 		*gettail_sep(p) = NUL;
16983 	}
16984 
16985 	rettv->vval.v_string = p;
16986     }
16987 # else
16988     rettv->vval.v_string = vim_strsave(p);
16989 # endif
16990 #endif
16991 
16992     simplify_filename(rettv->vval.v_string);
16993 
16994 #ifdef HAVE_READLINK
16995 fail:
16996     vim_free(buf);
16997 #endif
16998     rettv->v_type = VAR_STRING;
16999 }
17000 
17001 /*
17002  * "reverse({list})" function
17003  */
17004     static void
17005 f_reverse(typval_T *argvars, typval_T *rettv)
17006 {
17007     list_T	*l;
17008     listitem_T	*li, *ni;
17009 
17010     if (argvars[0].v_type != VAR_LIST)
17011 	EMSG2(_(e_listarg), "reverse()");
17012     else if ((l = argvars[0].vval.v_list) != NULL
17013 	    && !tv_check_lock(l->lv_lock,
17014 				    (char_u *)N_("reverse() argument"), TRUE))
17015     {
17016 	li = l->lv_last;
17017 	l->lv_first = l->lv_last = NULL;
17018 	l->lv_len = 0;
17019 	while (li != NULL)
17020 	{
17021 	    ni = li->li_prev;
17022 	    list_append(l, li);
17023 	    li = ni;
17024 	}
17025 	rettv->vval.v_list = l;
17026 	rettv->v_type = VAR_LIST;
17027 	++l->lv_refcount;
17028 	l->lv_idx = l->lv_len - l->lv_idx - 1;
17029     }
17030 }
17031 
17032 #define SP_NOMOVE	0x01	    /* don't move cursor */
17033 #define SP_REPEAT	0x02	    /* repeat to find outer pair */
17034 #define SP_RETCOUNT	0x04	    /* return matchcount */
17035 #define SP_SETPCMARK	0x08	    /* set previous context mark */
17036 #define SP_START	0x10	    /* accept match at start position */
17037 #define SP_SUBPAT	0x20	    /* return nr of matching sub-pattern */
17038 #define SP_END		0x40	    /* leave cursor at end of match */
17039 #define SP_COLUMN	0x80	    /* start at cursor column */
17040 
17041 static int get_search_arg(typval_T *varp, int *flagsp);
17042 
17043 /*
17044  * Get flags for a search function.
17045  * Possibly sets "p_ws".
17046  * Returns BACKWARD, FORWARD or zero (for an error).
17047  */
17048     static int
17049 get_search_arg(typval_T *varp, int *flagsp)
17050 {
17051     int		dir = FORWARD;
17052     char_u	*flags;
17053     char_u	nbuf[NUMBUFLEN];
17054     int		mask;
17055 
17056     if (varp->v_type != VAR_UNKNOWN)
17057     {
17058 	flags = get_tv_string_buf_chk(varp, nbuf);
17059 	if (flags == NULL)
17060 	    return 0;		/* type error; errmsg already given */
17061 	while (*flags != NUL)
17062 	{
17063 	    switch (*flags)
17064 	    {
17065 		case 'b': dir = BACKWARD; break;
17066 		case 'w': p_ws = TRUE; break;
17067 		case 'W': p_ws = FALSE; break;
17068 		default:  mask = 0;
17069 			  if (flagsp != NULL)
17070 			     switch (*flags)
17071 			     {
17072 				 case 'c': mask = SP_START; break;
17073 				 case 'e': mask = SP_END; break;
17074 				 case 'm': mask = SP_RETCOUNT; break;
17075 				 case 'n': mask = SP_NOMOVE; break;
17076 				 case 'p': mask = SP_SUBPAT; break;
17077 				 case 'r': mask = SP_REPEAT; break;
17078 				 case 's': mask = SP_SETPCMARK; break;
17079 				 case 'z': mask = SP_COLUMN; break;
17080 			     }
17081 			  if (mask == 0)
17082 			  {
17083 			      EMSG2(_(e_invarg2), flags);
17084 			      dir = 0;
17085 			  }
17086 			  else
17087 			      *flagsp |= mask;
17088 	    }
17089 	    if (dir == 0)
17090 		break;
17091 	    ++flags;
17092 	}
17093     }
17094     return dir;
17095 }
17096 
17097 /*
17098  * Shared by search() and searchpos() functions.
17099  */
17100     static int
17101 search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
17102 {
17103     int		flags;
17104     char_u	*pat;
17105     pos_T	pos;
17106     pos_T	save_cursor;
17107     int		save_p_ws = p_ws;
17108     int		dir;
17109     int		retval = 0;	/* default: FAIL */
17110     long	lnum_stop = 0;
17111     proftime_T	tm;
17112 #ifdef FEAT_RELTIME
17113     long	time_limit = 0;
17114 #endif
17115     int		options = SEARCH_KEEP;
17116     int		subpatnum;
17117 
17118     pat = get_tv_string(&argvars[0]);
17119     dir = get_search_arg(&argvars[1], flagsp);	/* may set p_ws */
17120     if (dir == 0)
17121 	goto theend;
17122     flags = *flagsp;
17123     if (flags & SP_START)
17124 	options |= SEARCH_START;
17125     if (flags & SP_END)
17126 	options |= SEARCH_END;
17127     if (flags & SP_COLUMN)
17128 	options |= SEARCH_COL;
17129 
17130     /* Optional arguments: line number to stop searching and timeout. */
17131     if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
17132     {
17133 	lnum_stop = get_tv_number_chk(&argvars[2], NULL);
17134 	if (lnum_stop < 0)
17135 	    goto theend;
17136 #ifdef FEAT_RELTIME
17137 	if (argvars[3].v_type != VAR_UNKNOWN)
17138 	{
17139 	    time_limit = get_tv_number_chk(&argvars[3], NULL);
17140 	    if (time_limit < 0)
17141 		goto theend;
17142 	}
17143 #endif
17144     }
17145 
17146 #ifdef FEAT_RELTIME
17147     /* Set the time limit, if there is one. */
17148     profile_setlimit(time_limit, &tm);
17149 #endif
17150 
17151     /*
17152      * This function does not accept SP_REPEAT and SP_RETCOUNT flags.
17153      * Check to make sure only those flags are set.
17154      * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both
17155      * flags cannot be set. Check for that condition also.
17156      */
17157     if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0)
17158 	    || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)))
17159     {
17160 	EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
17161 	goto theend;
17162     }
17163 
17164     pos = save_cursor = curwin->w_cursor;
17165     subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
17166 				options, RE_SEARCH, (linenr_T)lnum_stop, &tm);
17167     if (subpatnum != FAIL)
17168     {
17169 	if (flags & SP_SUBPAT)
17170 	    retval = subpatnum;
17171 	else
17172 	    retval = pos.lnum;
17173 	if (flags & SP_SETPCMARK)
17174 	    setpcmark();
17175 	curwin->w_cursor = pos;
17176 	if (match_pos != NULL)
17177 	{
17178 	    /* Store the match cursor position */
17179 	    match_pos->lnum = pos.lnum;
17180 	    match_pos->col = pos.col + 1;
17181 	}
17182 	/* "/$" will put the cursor after the end of the line, may need to
17183 	 * correct that here */
17184 	check_cursor();
17185     }
17186 
17187     /* If 'n' flag is used: restore cursor position. */
17188     if (flags & SP_NOMOVE)
17189 	curwin->w_cursor = save_cursor;
17190     else
17191 	curwin->w_set_curswant = TRUE;
17192 theend:
17193     p_ws = save_p_ws;
17194 
17195     return retval;
17196 }
17197 
17198 #ifdef FEAT_FLOAT
17199 
17200 /*
17201  * round() is not in C90, use ceil() or floor() instead.
17202  */
17203     float_T
17204 vim_round(float_T f)
17205 {
17206     return f > 0 ? floor(f + 0.5) : ceil(f - 0.5);
17207 }
17208 
17209 /*
17210  * "round({float})" function
17211  */
17212     static void
17213 f_round(typval_T *argvars, typval_T *rettv)
17214 {
17215     float_T	f = 0.0;
17216 
17217     rettv->v_type = VAR_FLOAT;
17218     if (get_float_arg(argvars, &f) == OK)
17219 	rettv->vval.v_float = vim_round(f);
17220     else
17221 	rettv->vval.v_float = 0.0;
17222 }
17223 #endif
17224 
17225 /*
17226  * "screenattr()" function
17227  */
17228     static void
17229 f_screenattr(typval_T *argvars, typval_T *rettv)
17230 {
17231     int		row;
17232     int		col;
17233     int		c;
17234 
17235     row = get_tv_number_chk(&argvars[0], NULL) - 1;
17236     col = get_tv_number_chk(&argvars[1], NULL) - 1;
17237     if (row < 0 || row >= screen_Rows
17238 	    || col < 0 || col >= screen_Columns)
17239 	c = -1;
17240     else
17241 	c = ScreenAttrs[LineOffset[row] + col];
17242     rettv->vval.v_number = c;
17243 }
17244 
17245 /*
17246  * "screenchar()" function
17247  */
17248     static void
17249 f_screenchar(typval_T *argvars, typval_T *rettv)
17250 {
17251     int		row;
17252     int		col;
17253     int		off;
17254     int		c;
17255 
17256     row = get_tv_number_chk(&argvars[0], NULL) - 1;
17257     col = get_tv_number_chk(&argvars[1], NULL) - 1;
17258     if (row < 0 || row >= screen_Rows
17259 	    || col < 0 || col >= screen_Columns)
17260 	c = -1;
17261     else
17262     {
17263 	off = LineOffset[row] + col;
17264 #ifdef FEAT_MBYTE
17265 	if (enc_utf8 && ScreenLinesUC[off] != 0)
17266 	    c = ScreenLinesUC[off];
17267 	else
17268 #endif
17269 	    c = ScreenLines[off];
17270     }
17271     rettv->vval.v_number = c;
17272 }
17273 
17274 /*
17275  * "screencol()" function
17276  *
17277  * First column is 1 to be consistent with virtcol().
17278  */
17279     static void
17280 f_screencol(typval_T *argvars UNUSED, typval_T *rettv)
17281 {
17282     rettv->vval.v_number = screen_screencol() + 1;
17283 }
17284 
17285 /*
17286  * "screenrow()" function
17287  */
17288     static void
17289 f_screenrow(typval_T *argvars UNUSED, typval_T *rettv)
17290 {
17291     rettv->vval.v_number = screen_screenrow() + 1;
17292 }
17293 
17294 /*
17295  * "search()" function
17296  */
17297     static void
17298 f_search(typval_T *argvars, typval_T *rettv)
17299 {
17300     int		flags = 0;
17301 
17302     rettv->vval.v_number = search_cmn(argvars, NULL, &flags);
17303 }
17304 
17305 /*
17306  * "searchdecl()" function
17307  */
17308     static void
17309 f_searchdecl(typval_T *argvars, typval_T *rettv)
17310 {
17311     int		locally = 1;
17312     int		thisblock = 0;
17313     int		error = FALSE;
17314     char_u	*name;
17315 
17316     rettv->vval.v_number = 1;	/* default: FAIL */
17317 
17318     name = get_tv_string_chk(&argvars[0]);
17319     if (argvars[1].v_type != VAR_UNKNOWN)
17320     {
17321 	locally = get_tv_number_chk(&argvars[1], &error) == 0;
17322 	if (!error && argvars[2].v_type != VAR_UNKNOWN)
17323 	    thisblock = get_tv_number_chk(&argvars[2], &error) != 0;
17324     }
17325     if (!error && name != NULL)
17326 	rettv->vval.v_number = find_decl(name, (int)STRLEN(name),
17327 				     locally, thisblock, SEARCH_KEEP) == FAIL;
17328 }
17329 
17330 /*
17331  * Used by searchpair() and searchpairpos()
17332  */
17333     static int
17334 searchpair_cmn(typval_T *argvars, pos_T *match_pos)
17335 {
17336     char_u	*spat, *mpat, *epat;
17337     char_u	*skip;
17338     int		save_p_ws = p_ws;
17339     int		dir;
17340     int		flags = 0;
17341     char_u	nbuf1[NUMBUFLEN];
17342     char_u	nbuf2[NUMBUFLEN];
17343     char_u	nbuf3[NUMBUFLEN];
17344     int		retval = 0;		/* default: FAIL */
17345     long	lnum_stop = 0;
17346     long	time_limit = 0;
17347 
17348     /* Get the three pattern arguments: start, middle, end. */
17349     spat = get_tv_string_chk(&argvars[0]);
17350     mpat = get_tv_string_buf_chk(&argvars[1], nbuf1);
17351     epat = get_tv_string_buf_chk(&argvars[2], nbuf2);
17352     if (spat == NULL || mpat == NULL || epat == NULL)
17353 	goto theend;	    /* type error */
17354 
17355     /* Handle the optional fourth argument: flags */
17356     dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
17357     if (dir == 0)
17358 	goto theend;
17359 
17360     /* Don't accept SP_END or SP_SUBPAT.
17361      * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set.
17362      */
17363     if ((flags & (SP_END | SP_SUBPAT)) != 0
17364 	    || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)))
17365     {
17366 	EMSG2(_(e_invarg2), get_tv_string(&argvars[3]));
17367 	goto theend;
17368     }
17369 
17370     /* Using 'r' implies 'W', otherwise it doesn't work. */
17371     if (flags & SP_REPEAT)
17372 	p_ws = FALSE;
17373 
17374     /* Optional fifth argument: skip expression */
17375     if (argvars[3].v_type == VAR_UNKNOWN
17376 	    || argvars[4].v_type == VAR_UNKNOWN)
17377 	skip = (char_u *)"";
17378     else
17379     {
17380 	skip = get_tv_string_buf_chk(&argvars[4], nbuf3);
17381 	if (argvars[5].v_type != VAR_UNKNOWN)
17382 	{
17383 	    lnum_stop = get_tv_number_chk(&argvars[5], NULL);
17384 	    if (lnum_stop < 0)
17385 		goto theend;
17386 #ifdef FEAT_RELTIME
17387 	    if (argvars[6].v_type != VAR_UNKNOWN)
17388 	    {
17389 		time_limit = get_tv_number_chk(&argvars[6], NULL);
17390 		if (time_limit < 0)
17391 		    goto theend;
17392 	    }
17393 #endif
17394 	}
17395     }
17396     if (skip == NULL)
17397 	goto theend;	    /* type error */
17398 
17399     retval = do_searchpair(spat, mpat, epat, dir, skip, flags,
17400 					    match_pos, lnum_stop, time_limit);
17401 
17402 theend:
17403     p_ws = save_p_ws;
17404 
17405     return retval;
17406 }
17407 
17408 /*
17409  * "searchpair()" function
17410  */
17411     static void
17412 f_searchpair(typval_T *argvars, typval_T *rettv)
17413 {
17414     rettv->vval.v_number = searchpair_cmn(argvars, NULL);
17415 }
17416 
17417 /*
17418  * "searchpairpos()" function
17419  */
17420     static void
17421 f_searchpairpos(typval_T *argvars, typval_T *rettv)
17422 {
17423     pos_T	match_pos;
17424     int		lnum = 0;
17425     int		col = 0;
17426 
17427     if (rettv_list_alloc(rettv) == FAIL)
17428 	return;
17429 
17430     if (searchpair_cmn(argvars, &match_pos) > 0)
17431     {
17432 	lnum = match_pos.lnum;
17433 	col = match_pos.col;
17434     }
17435 
17436     list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
17437     list_append_number(rettv->vval.v_list, (varnumber_T)col);
17438 }
17439 
17440 /*
17441  * Search for a start/middle/end thing.
17442  * Used by searchpair(), see its documentation for the details.
17443  * Returns 0 or -1 for no match,
17444  */
17445     long
17446 do_searchpair(
17447     char_u	*spat,	    /* start pattern */
17448     char_u	*mpat,	    /* middle pattern */
17449     char_u	*epat,	    /* end pattern */
17450     int		dir,	    /* BACKWARD or FORWARD */
17451     char_u	*skip,	    /* skip expression */
17452     int		flags,	    /* SP_SETPCMARK and other SP_ values */
17453     pos_T	*match_pos,
17454     linenr_T	lnum_stop,  /* stop at this line if not zero */
17455     long	time_limit UNUSED) /* stop after this many msec */
17456 {
17457     char_u	*save_cpo;
17458     char_u	*pat, *pat2 = NULL, *pat3 = NULL;
17459     long	retval = 0;
17460     pos_T	pos;
17461     pos_T	firstpos;
17462     pos_T	foundpos;
17463     pos_T	save_cursor;
17464     pos_T	save_pos;
17465     int		n;
17466     int		r;
17467     int		nest = 1;
17468     int		err;
17469     int		options = SEARCH_KEEP;
17470     proftime_T	tm;
17471 
17472     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
17473     save_cpo = p_cpo;
17474     p_cpo = empty_option;
17475 
17476 #ifdef FEAT_RELTIME
17477     /* Set the time limit, if there is one. */
17478     profile_setlimit(time_limit, &tm);
17479 #endif
17480 
17481     /* Make two search patterns: start/end (pat2, for in nested pairs) and
17482      * start/middle/end (pat3, for the top pair). */
17483     pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
17484     pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
17485     if (pat2 == NULL || pat3 == NULL)
17486 	goto theend;
17487     sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
17488     if (*mpat == NUL)
17489 	STRCPY(pat3, pat2);
17490     else
17491 	sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
17492 							    spat, epat, mpat);
17493     if (flags & SP_START)
17494 	options |= SEARCH_START;
17495 
17496     save_cursor = curwin->w_cursor;
17497     pos = curwin->w_cursor;
17498     clearpos(&firstpos);
17499     clearpos(&foundpos);
17500     pat = pat3;
17501     for (;;)
17502     {
17503 	n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
17504 					   options, RE_SEARCH, lnum_stop, &tm);
17505 	if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
17506 	    /* didn't find it or found the first match again: FAIL */
17507 	    break;
17508 
17509 	if (firstpos.lnum == 0)
17510 	    firstpos = pos;
17511 	if (equalpos(pos, foundpos))
17512 	{
17513 	    /* Found the same position again.  Can happen with a pattern that
17514 	     * has "\zs" at the end and searching backwards.  Advance one
17515 	     * character and try again. */
17516 	    if (dir == BACKWARD)
17517 		decl(&pos);
17518 	    else
17519 		incl(&pos);
17520 	}
17521 	foundpos = pos;
17522 
17523 	/* clear the start flag to avoid getting stuck here */
17524 	options &= ~SEARCH_START;
17525 
17526 	/* If the skip pattern matches, ignore this match. */
17527 	if (*skip != NUL)
17528 	{
17529 	    save_pos = curwin->w_cursor;
17530 	    curwin->w_cursor = pos;
17531 	    r = eval_to_bool(skip, &err, NULL, FALSE);
17532 	    curwin->w_cursor = save_pos;
17533 	    if (err)
17534 	    {
17535 		/* Evaluating {skip} caused an error, break here. */
17536 		curwin->w_cursor = save_cursor;
17537 		retval = -1;
17538 		break;
17539 	    }
17540 	    if (r)
17541 		continue;
17542 	}
17543 
17544 	if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2))
17545 	{
17546 	    /* Found end when searching backwards or start when searching
17547 	     * forward: nested pair. */
17548 	    ++nest;
17549 	    pat = pat2;		/* nested, don't search for middle */
17550 	}
17551 	else
17552 	{
17553 	    /* Found end when searching forward or start when searching
17554 	     * backward: end of (nested) pair; or found middle in outer pair. */
17555 	    if (--nest == 1)
17556 		pat = pat3;	/* outer level, search for middle */
17557 	}
17558 
17559 	if (nest == 0)
17560 	{
17561 	    /* Found the match: return matchcount or line number. */
17562 	    if (flags & SP_RETCOUNT)
17563 		++retval;
17564 	    else
17565 		retval = pos.lnum;
17566 	    if (flags & SP_SETPCMARK)
17567 		setpcmark();
17568 	    curwin->w_cursor = pos;
17569 	    if (!(flags & SP_REPEAT))
17570 		break;
17571 	    nest = 1;	    /* search for next unmatched */
17572 	}
17573     }
17574 
17575     if (match_pos != NULL)
17576     {
17577 	/* Store the match cursor position */
17578 	match_pos->lnum = curwin->w_cursor.lnum;
17579 	match_pos->col = curwin->w_cursor.col + 1;
17580     }
17581 
17582     /* If 'n' flag is used or search failed: restore cursor position. */
17583     if ((flags & SP_NOMOVE) || retval == 0)
17584 	curwin->w_cursor = save_cursor;
17585 
17586 theend:
17587     vim_free(pat2);
17588     vim_free(pat3);
17589     if (p_cpo == empty_option)
17590 	p_cpo = save_cpo;
17591     else
17592 	/* Darn, evaluating the {skip} expression changed the value. */
17593 	free_string_option(save_cpo);
17594 
17595     return retval;
17596 }
17597 
17598 /*
17599  * "searchpos()" function
17600  */
17601     static void
17602 f_searchpos(typval_T *argvars, typval_T *rettv)
17603 {
17604     pos_T	match_pos;
17605     int		lnum = 0;
17606     int		col = 0;
17607     int		n;
17608     int		flags = 0;
17609 
17610     if (rettv_list_alloc(rettv) == FAIL)
17611 	return;
17612 
17613     n = search_cmn(argvars, &match_pos, &flags);
17614     if (n > 0)
17615     {
17616 	lnum = match_pos.lnum;
17617 	col = match_pos.col;
17618     }
17619 
17620     list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
17621     list_append_number(rettv->vval.v_list, (varnumber_T)col);
17622     if (flags & SP_SUBPAT)
17623 	list_append_number(rettv->vval.v_list, (varnumber_T)n);
17624 }
17625 
17626     static void
17627 f_server2client(typval_T *argvars UNUSED, typval_T *rettv)
17628 {
17629 #ifdef FEAT_CLIENTSERVER
17630     char_u	buf[NUMBUFLEN];
17631     char_u	*server = get_tv_string_chk(&argvars[0]);
17632     char_u	*reply = get_tv_string_buf_chk(&argvars[1], buf);
17633 
17634     rettv->vval.v_number = -1;
17635     if (server == NULL || reply == NULL)
17636 	return;
17637     if (check_restricted() || check_secure())
17638 	return;
17639 # ifdef FEAT_X11
17640     if (check_connection() == FAIL)
17641 	return;
17642 # endif
17643 
17644     if (serverSendReply(server, reply) < 0)
17645     {
17646 	EMSG(_("E258: Unable to send to client"));
17647 	return;
17648     }
17649     rettv->vval.v_number = 0;
17650 #else
17651     rettv->vval.v_number = -1;
17652 #endif
17653 }
17654 
17655     static void
17656 f_serverlist(typval_T *argvars UNUSED, typval_T *rettv)
17657 {
17658     char_u	*r = NULL;
17659 
17660 #ifdef FEAT_CLIENTSERVER
17661 # ifdef WIN32
17662     r = serverGetVimNames();
17663 # else
17664     make_connection();
17665     if (X_DISPLAY != NULL)
17666 	r = serverGetVimNames(X_DISPLAY);
17667 # endif
17668 #endif
17669     rettv->v_type = VAR_STRING;
17670     rettv->vval.v_string = r;
17671 }
17672 
17673 /*
17674  * "setbufvar()" function
17675  */
17676     static void
17677 f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
17678 {
17679     buf_T	*buf;
17680     aco_save_T	aco;
17681     char_u	*varname, *bufvarname;
17682     typval_T	*varp;
17683     char_u	nbuf[NUMBUFLEN];
17684 
17685     if (check_restricted() || check_secure())
17686 	return;
17687     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
17688     varname = get_tv_string_chk(&argvars[1]);
17689     buf = get_buf_tv(&argvars[0], FALSE);
17690     varp = &argvars[2];
17691 
17692     if (buf != NULL && varname != NULL && varp != NULL)
17693     {
17694 	/* set curbuf to be our buf, temporarily */
17695 	aucmd_prepbuf(&aco, buf);
17696 
17697 	if (*varname == '&')
17698 	{
17699 	    long	numval;
17700 	    char_u	*strval;
17701 	    int		error = FALSE;
17702 
17703 	    ++varname;
17704 	    numval = get_tv_number_chk(varp, &error);
17705 	    strval = get_tv_string_buf_chk(varp, nbuf);
17706 	    if (!error && strval != NULL)
17707 		set_option_value(varname, numval, strval, OPT_LOCAL);
17708 	}
17709 	else
17710 	{
17711 	    bufvarname = alloc((unsigned)STRLEN(varname) + 3);
17712 	    if (bufvarname != NULL)
17713 	    {
17714 		STRCPY(bufvarname, "b:");
17715 		STRCPY(bufvarname + 2, varname);
17716 		set_var(bufvarname, varp, TRUE);
17717 		vim_free(bufvarname);
17718 	    }
17719 	}
17720 
17721 	/* reset notion of buffer */
17722 	aucmd_restbuf(&aco);
17723     }
17724 }
17725 
17726     static void
17727 f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED)
17728 {
17729     dict_T	*d;
17730     dictitem_T	*di;
17731     char_u	*csearch;
17732 
17733     if (argvars[0].v_type != VAR_DICT)
17734     {
17735 	EMSG(_(e_dictreq));
17736 	return;
17737     }
17738 
17739     if ((d = argvars[0].vval.v_dict) != NULL)
17740     {
17741 	csearch = get_dict_string(d, (char_u *)"char", FALSE);
17742 	if (csearch != NULL)
17743 	{
17744 #ifdef FEAT_MBYTE
17745 	    if (enc_utf8)
17746 	    {
17747 		int pcc[MAX_MCO];
17748 		int c = utfc_ptr2char(csearch, pcc);
17749 
17750 		set_last_csearch(c, csearch, utfc_ptr2len(csearch));
17751 	    }
17752 	    else
17753 #endif
17754 		set_last_csearch(PTR2CHAR(csearch),
17755 						csearch, MB_PTR2LEN(csearch));
17756 	}
17757 
17758 	di = dict_find(d, (char_u *)"forward", -1);
17759 	if (di != NULL)
17760 	    set_csearch_direction(get_tv_number(&di->di_tv)
17761 							? FORWARD : BACKWARD);
17762 
17763 	di = dict_find(d, (char_u *)"until", -1);
17764 	if (di != NULL)
17765 	    set_csearch_until(!!get_tv_number(&di->di_tv));
17766     }
17767 }
17768 
17769 /*
17770  * "setcmdpos()" function
17771  */
17772     static void
17773 f_setcmdpos(typval_T *argvars, typval_T *rettv)
17774 {
17775     int		pos = (int)get_tv_number(&argvars[0]) - 1;
17776 
17777     if (pos >= 0)
17778 	rettv->vval.v_number = set_cmdline_pos(pos);
17779 }
17780 
17781 /*
17782  * "setfperm({fname}, {mode})" function
17783  */
17784     static void
17785 f_setfperm(typval_T *argvars, typval_T *rettv)
17786 {
17787     char_u	*fname;
17788     char_u	modebuf[NUMBUFLEN];
17789     char_u	*mode_str;
17790     int		i;
17791     int		mask;
17792     int		mode = 0;
17793 
17794     rettv->vval.v_number = 0;
17795     fname = get_tv_string_chk(&argvars[0]);
17796     if (fname == NULL)
17797 	return;
17798     mode_str = get_tv_string_buf_chk(&argvars[1], modebuf);
17799     if (mode_str == NULL)
17800 	return;
17801     if (STRLEN(mode_str) != 9)
17802     {
17803 	EMSG2(_(e_invarg2), mode_str);
17804 	return;
17805     }
17806 
17807     mask = 1;
17808     for (i = 8; i >= 0; --i)
17809     {
17810 	if (mode_str[i] != '-')
17811 	    mode |= mask;
17812 	mask = mask << 1;
17813     }
17814     rettv->vval.v_number = mch_setperm(fname, mode) == OK;
17815 }
17816 
17817 /*
17818  * "setline()" function
17819  */
17820     static void
17821 f_setline(typval_T *argvars, typval_T *rettv)
17822 {
17823     linenr_T	lnum;
17824     char_u	*line = NULL;
17825     list_T	*l = NULL;
17826     listitem_T	*li = NULL;
17827     long	added = 0;
17828     linenr_T	lcount = curbuf->b_ml.ml_line_count;
17829 
17830     lnum = get_tv_lnum(&argvars[0]);
17831     if (argvars[1].v_type == VAR_LIST)
17832     {
17833 	l = argvars[1].vval.v_list;
17834 	li = l->lv_first;
17835     }
17836     else
17837 	line = get_tv_string_chk(&argvars[1]);
17838 
17839     /* default result is zero == OK */
17840     for (;;)
17841     {
17842 	if (l != NULL)
17843 	{
17844 	    /* list argument, get next string */
17845 	    if (li == NULL)
17846 		break;
17847 	    line = get_tv_string_chk(&li->li_tv);
17848 	    li = li->li_next;
17849 	}
17850 
17851 	rettv->vval.v_number = 1;	/* FAIL */
17852 	if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
17853 	    break;
17854 
17855 	/* When coming here from Insert mode, sync undo, so that this can be
17856 	 * undone separately from what was previously inserted. */
17857 	if (u_sync_once == 2)
17858 	{
17859 	    u_sync_once = 1; /* notify that u_sync() was called */
17860 	    u_sync(TRUE);
17861 	}
17862 
17863 	if (lnum <= curbuf->b_ml.ml_line_count)
17864 	{
17865 	    /* existing line, replace it */
17866 	    if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK)
17867 	    {
17868 		changed_bytes(lnum, 0);
17869 		if (lnum == curwin->w_cursor.lnum)
17870 		    check_cursor_col();
17871 		rettv->vval.v_number = 0;	/* OK */
17872 	    }
17873 	}
17874 	else if (added > 0 || u_save(lnum - 1, lnum) == OK)
17875 	{
17876 	    /* lnum is one past the last line, append the line */
17877 	    ++added;
17878 	    if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
17879 		rettv->vval.v_number = 0;	/* OK */
17880 	}
17881 
17882 	if (l == NULL)			/* only one string argument */
17883 	    break;
17884 	++lnum;
17885     }
17886 
17887     if (added > 0)
17888 	appended_lines_mark(lcount, added);
17889 }
17890 
17891 static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv);
17892 
17893 /*
17894  * Used by "setqflist()" and "setloclist()" functions
17895  */
17896     static void
17897 set_qf_ll_list(
17898     win_T	*wp UNUSED,
17899     typval_T	*list_arg UNUSED,
17900     typval_T	*action_arg UNUSED,
17901     typval_T	*rettv)
17902 {
17903 #ifdef FEAT_QUICKFIX
17904     char_u	*act;
17905     int		action = ' ';
17906 #endif
17907 
17908     rettv->vval.v_number = -1;
17909 
17910 #ifdef FEAT_QUICKFIX
17911     if (list_arg->v_type != VAR_LIST)
17912 	EMSG(_(e_listreq));
17913     else
17914     {
17915 	list_T  *l = list_arg->vval.v_list;
17916 
17917 	if (action_arg->v_type == VAR_STRING)
17918 	{
17919 	    act = get_tv_string_chk(action_arg);
17920 	    if (act == NULL)
17921 		return;		/* type error; errmsg already given */
17922 	    if (*act == 'a' || *act == 'r')
17923 		action = *act;
17924 	}
17925 
17926 	if (l != NULL && set_errorlist(wp, l, action,
17927 	       (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
17928 	    rettv->vval.v_number = 0;
17929     }
17930 #endif
17931 }
17932 
17933 /*
17934  * "setloclist()" function
17935  */
17936     static void
17937 f_setloclist(typval_T *argvars, typval_T *rettv)
17938 {
17939     win_T	*win;
17940 
17941     rettv->vval.v_number = -1;
17942 
17943     win = find_win_by_nr(&argvars[0], NULL);
17944     if (win != NULL)
17945 	set_qf_ll_list(win, &argvars[1], &argvars[2], rettv);
17946 }
17947 
17948 /*
17949  * "setmatches()" function
17950  */
17951     static void
17952 f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
17953 {
17954 #ifdef FEAT_SEARCH_EXTRA
17955     list_T	*l;
17956     listitem_T	*li;
17957     dict_T	*d;
17958     list_T	*s = NULL;
17959 
17960     rettv->vval.v_number = -1;
17961     if (argvars[0].v_type != VAR_LIST)
17962     {
17963 	EMSG(_(e_listreq));
17964 	return;
17965     }
17966     if ((l = argvars[0].vval.v_list) != NULL)
17967     {
17968 
17969 	/* To some extent make sure that we are dealing with a list from
17970 	 * "getmatches()". */
17971 	li = l->lv_first;
17972 	while (li != NULL)
17973 	{
17974 	    if (li->li_tv.v_type != VAR_DICT
17975 		    || (d = li->li_tv.vval.v_dict) == NULL)
17976 	    {
17977 		EMSG(_(e_invarg));
17978 		return;
17979 	    }
17980 	    if (!(dict_find(d, (char_u *)"group", -1) != NULL
17981 			&& (dict_find(d, (char_u *)"pattern", -1) != NULL
17982 			    || dict_find(d, (char_u *)"pos1", -1) != NULL)
17983 			&& dict_find(d, (char_u *)"priority", -1) != NULL
17984 			&& dict_find(d, (char_u *)"id", -1) != NULL))
17985 	    {
17986 		EMSG(_(e_invarg));
17987 		return;
17988 	    }
17989 	    li = li->li_next;
17990 	}
17991 
17992 	clear_matches(curwin);
17993 	li = l->lv_first;
17994 	while (li != NULL)
17995 	{
17996 	    int		i = 0;
17997 	    char_u	buf[5];
17998 	    dictitem_T  *di;
17999 	    char_u	*group;
18000 	    int		priority;
18001 	    int		id;
18002 	    char_u	*conceal;
18003 
18004 	    d = li->li_tv.vval.v_dict;
18005 	    if (dict_find(d, (char_u *)"pattern", -1) == NULL)
18006 	    {
18007 		if (s == NULL)
18008 		{
18009 		    s = list_alloc();
18010 		    if (s == NULL)
18011 			return;
18012 		}
18013 
18014 		/* match from matchaddpos() */
18015 		for (i = 1; i < 9; i++)
18016 		{
18017 		    sprintf((char *)buf, (char *)"pos%d", i);
18018 		    if ((di = dict_find(d, (char_u *)buf, -1)) != NULL)
18019 		    {
18020 			if (di->di_tv.v_type != VAR_LIST)
18021 			    return;
18022 
18023 			list_append_tv(s, &di->di_tv);
18024 			s->lv_refcount++;
18025 		    }
18026 		    else
18027 			break;
18028 		}
18029 	    }
18030 
18031 	    group = get_dict_string(d, (char_u *)"group", FALSE);
18032 	    priority = (int)get_dict_number(d, (char_u *)"priority");
18033 	    id = (int)get_dict_number(d, (char_u *)"id");
18034 	    conceal = dict_find(d, (char_u *)"conceal", -1) != NULL
18035 			      ? get_dict_string(d, (char_u *)"conceal", FALSE)
18036 			      : NULL;
18037 	    if (i == 0)
18038 	    {
18039 		match_add(curwin, group,
18040 		    get_dict_string(d, (char_u *)"pattern", FALSE),
18041 		    priority, id, NULL, conceal);
18042 	    }
18043 	    else
18044 	    {
18045 		match_add(curwin, group, NULL, priority, id, s, conceal);
18046 		list_unref(s);
18047 		s = NULL;
18048 	    }
18049 
18050 	    li = li->li_next;
18051 	}
18052 	rettv->vval.v_number = 0;
18053     }
18054 #endif
18055 }
18056 
18057 /*
18058  * "setpos()" function
18059  */
18060     static void
18061 f_setpos(typval_T *argvars, typval_T *rettv)
18062 {
18063     pos_T	pos;
18064     int		fnum;
18065     char_u	*name;
18066     colnr_T	curswant = -1;
18067 
18068     rettv->vval.v_number = -1;
18069     name = get_tv_string_chk(argvars);
18070     if (name != NULL)
18071     {
18072 	if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK)
18073 	{
18074 	    if (--pos.col < 0)
18075 		pos.col = 0;
18076 	    if (name[0] == '.' && name[1] == NUL)
18077 	    {
18078 		/* set cursor */
18079 		if (fnum == curbuf->b_fnum)
18080 		{
18081 		    curwin->w_cursor = pos;
18082 		    if (curswant >= 0)
18083 		    {
18084 			curwin->w_curswant = curswant - 1;
18085 			curwin->w_set_curswant = FALSE;
18086 		    }
18087 		    check_cursor();
18088 		    rettv->vval.v_number = 0;
18089 		}
18090 		else
18091 		    EMSG(_(e_invarg));
18092 	    }
18093 	    else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL)
18094 	    {
18095 		/* set mark */
18096 		if (setmark_pos(name[1], &pos, fnum) == OK)
18097 		    rettv->vval.v_number = 0;
18098 	    }
18099 	    else
18100 		EMSG(_(e_invarg));
18101 	}
18102     }
18103 }
18104 
18105 /*
18106  * "setqflist()" function
18107  */
18108     static void
18109 f_setqflist(typval_T *argvars, typval_T *rettv)
18110 {
18111     set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv);
18112 }
18113 
18114 /*
18115  * "setreg()" function
18116  */
18117     static void
18118 f_setreg(typval_T *argvars, typval_T *rettv)
18119 {
18120     int		regname;
18121     char_u	*strregname;
18122     char_u	*stropt;
18123     char_u	*strval;
18124     int		append;
18125     char_u	yank_type;
18126     long	block_len;
18127 
18128     block_len = -1;
18129     yank_type = MAUTO;
18130     append = FALSE;
18131 
18132     strregname = get_tv_string_chk(argvars);
18133     rettv->vval.v_number = 1;		/* FAIL is default */
18134 
18135     if (strregname == NULL)
18136 	return;		/* type error; errmsg already given */
18137     regname = *strregname;
18138     if (regname == 0 || regname == '@')
18139 	regname = '"';
18140 
18141     if (argvars[2].v_type != VAR_UNKNOWN)
18142     {
18143 	stropt = get_tv_string_chk(&argvars[2]);
18144 	if (stropt == NULL)
18145 	    return;		/* type error */
18146 	for (; *stropt != NUL; ++stropt)
18147 	    switch (*stropt)
18148 	    {
18149 		case 'a': case 'A':	/* append */
18150 		    append = TRUE;
18151 		    break;
18152 		case 'v': case 'c':	/* character-wise selection */
18153 		    yank_type = MCHAR;
18154 		    break;
18155 		case 'V': case 'l':	/* line-wise selection */
18156 		    yank_type = MLINE;
18157 		    break;
18158 		case 'b': case Ctrl_V:	/* block-wise selection */
18159 		    yank_type = MBLOCK;
18160 		    if (VIM_ISDIGIT(stropt[1]))
18161 		    {
18162 			++stropt;
18163 			block_len = getdigits(&stropt) - 1;
18164 			--stropt;
18165 		    }
18166 		    break;
18167 	    }
18168     }
18169 
18170     if (argvars[1].v_type == VAR_LIST)
18171     {
18172 	char_u		**lstval;
18173 	char_u		**allocval;
18174 	char_u		buf[NUMBUFLEN];
18175 	char_u		**curval;
18176 	char_u		**curallocval;
18177 	int		len = argvars[1].vval.v_list->lv_len;
18178 	listitem_T	*li;
18179 
18180 	/* First half: use for pointers to result lines; second half: use for
18181 	 * pointers to allocated copies. */
18182 	lstval = (char_u **)alloc(sizeof(char_u *) * ((len + 1) * 2));
18183 	if (lstval == NULL)
18184 	    return;
18185 	curval = lstval;
18186 	allocval = lstval + len + 2;
18187 	curallocval = allocval;
18188 
18189 	for (li = argvars[1].vval.v_list->lv_first; li != NULL;
18190 							     li = li->li_next)
18191 	{
18192 	    strval = get_tv_string_buf_chk(&li->li_tv, buf);
18193 	    if (strval == NULL)
18194 		goto free_lstval;
18195 	    if (strval == buf)
18196 	    {
18197 		/* Need to make a copy, next get_tv_string_buf_chk() will
18198 		 * overwrite the string. */
18199 		strval = vim_strsave(buf);
18200 		if (strval == NULL)
18201 		    goto free_lstval;
18202 		*curallocval++ = strval;
18203 	    }
18204 	    *curval++ = strval;
18205 	}
18206 	*curval++ = NULL;
18207 
18208 	write_reg_contents_lst(regname, lstval, -1,
18209 						append, yank_type, block_len);
18210 free_lstval:
18211 	while (curallocval > allocval)
18212 	    vim_free(*--curallocval);
18213 	vim_free(lstval);
18214     }
18215     else
18216     {
18217 	strval = get_tv_string_chk(&argvars[1]);
18218 	if (strval == NULL)
18219 	    return;
18220 	write_reg_contents_ex(regname, strval, -1,
18221 						append, yank_type, block_len);
18222     }
18223     rettv->vval.v_number = 0;
18224 }
18225 
18226 /*
18227  * "settabvar()" function
18228  */
18229     static void
18230 f_settabvar(typval_T *argvars, typval_T *rettv)
18231 {
18232 #ifdef FEAT_WINDOWS
18233     tabpage_T	*save_curtab;
18234     tabpage_T	*tp;
18235 #endif
18236     char_u	*varname, *tabvarname;
18237     typval_T	*varp;
18238 
18239     rettv->vval.v_number = 0;
18240 
18241     if (check_restricted() || check_secure())
18242 	return;
18243 
18244 #ifdef FEAT_WINDOWS
18245     tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
18246 #endif
18247     varname = get_tv_string_chk(&argvars[1]);
18248     varp = &argvars[2];
18249 
18250     if (varname != NULL && varp != NULL
18251 #ifdef FEAT_WINDOWS
18252 	    && tp != NULL
18253 #endif
18254 	    )
18255     {
18256 #ifdef FEAT_WINDOWS
18257 	save_curtab = curtab;
18258 	goto_tabpage_tp(tp, FALSE, FALSE);
18259 #endif
18260 
18261 	tabvarname = alloc((unsigned)STRLEN(varname) + 3);
18262 	if (tabvarname != NULL)
18263 	{
18264 	    STRCPY(tabvarname, "t:");
18265 	    STRCPY(tabvarname + 2, varname);
18266 	    set_var(tabvarname, varp, TRUE);
18267 	    vim_free(tabvarname);
18268 	}
18269 
18270 #ifdef FEAT_WINDOWS
18271 	/* Restore current tabpage */
18272 	if (valid_tabpage(save_curtab))
18273 	    goto_tabpage_tp(save_curtab, FALSE, FALSE);
18274 #endif
18275     }
18276 }
18277 
18278 /*
18279  * "settabwinvar()" function
18280  */
18281     static void
18282 f_settabwinvar(typval_T *argvars, typval_T *rettv)
18283 {
18284     setwinvar(argvars, rettv, 1);
18285 }
18286 
18287 /*
18288  * "setwinvar()" function
18289  */
18290     static void
18291 f_setwinvar(typval_T *argvars, typval_T *rettv)
18292 {
18293     setwinvar(argvars, rettv, 0);
18294 }
18295 
18296 /*
18297  * "setwinvar()" and "settabwinvar()" functions
18298  */
18299 
18300     static void
18301 setwinvar(typval_T *argvars, typval_T *rettv UNUSED, int off)
18302 {
18303     win_T	*win;
18304 #ifdef FEAT_WINDOWS
18305     win_T	*save_curwin;
18306     tabpage_T	*save_curtab;
18307     int		need_switch_win;
18308 #endif
18309     char_u	*varname, *winvarname;
18310     typval_T	*varp;
18311     char_u	nbuf[NUMBUFLEN];
18312     tabpage_T	*tp = NULL;
18313 
18314     if (check_restricted() || check_secure())
18315 	return;
18316 
18317 #ifdef FEAT_WINDOWS
18318     if (off == 1)
18319 	tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
18320     else
18321 	tp = curtab;
18322 #endif
18323     win = find_win_by_nr(&argvars[off], tp);
18324     varname = get_tv_string_chk(&argvars[off + 1]);
18325     varp = &argvars[off + 2];
18326 
18327     if (win != NULL && varname != NULL && varp != NULL)
18328     {
18329 #ifdef FEAT_WINDOWS
18330 	need_switch_win = !(tp == curtab && win == curwin);
18331 	if (!need_switch_win
18332 	       || switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK)
18333 #endif
18334 	{
18335 	    if (*varname == '&')
18336 	    {
18337 		long	numval;
18338 		char_u	*strval;
18339 		int		error = FALSE;
18340 
18341 		++varname;
18342 		numval = get_tv_number_chk(varp, &error);
18343 		strval = get_tv_string_buf_chk(varp, nbuf);
18344 		if (!error && strval != NULL)
18345 		    set_option_value(varname, numval, strval, OPT_LOCAL);
18346 	    }
18347 	    else
18348 	    {
18349 		winvarname = alloc((unsigned)STRLEN(varname) + 3);
18350 		if (winvarname != NULL)
18351 		{
18352 		    STRCPY(winvarname, "w:");
18353 		    STRCPY(winvarname + 2, varname);
18354 		    set_var(winvarname, varp, TRUE);
18355 		    vim_free(winvarname);
18356 		}
18357 	    }
18358 	}
18359 #ifdef FEAT_WINDOWS
18360 	if (need_switch_win)
18361 	    restore_win(save_curwin, save_curtab, TRUE);
18362 #endif
18363     }
18364 }
18365 
18366 #ifdef FEAT_CRYPT
18367 /*
18368  * "sha256({string})" function
18369  */
18370     static void
18371 f_sha256(typval_T *argvars, typval_T *rettv)
18372 {
18373     char_u	*p;
18374 
18375     p = get_tv_string(&argvars[0]);
18376     rettv->vval.v_string = vim_strsave(
18377 				    sha256_bytes(p, (int)STRLEN(p), NULL, 0));
18378     rettv->v_type = VAR_STRING;
18379 }
18380 #endif /* FEAT_CRYPT */
18381 
18382 /*
18383  * "shellescape({string})" function
18384  */
18385     static void
18386 f_shellescape(typval_T *argvars, typval_T *rettv)
18387 {
18388     rettv->vval.v_string = vim_strsave_shellescape(
18389 		get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]), TRUE);
18390     rettv->v_type = VAR_STRING;
18391 }
18392 
18393 /*
18394  * shiftwidth() function
18395  */
18396     static void
18397 f_shiftwidth(typval_T *argvars UNUSED, typval_T *rettv)
18398 {
18399     rettv->vval.v_number = get_sw_value(curbuf);
18400 }
18401 
18402 /*
18403  * "simplify()" function
18404  */
18405     static void
18406 f_simplify(typval_T *argvars, typval_T *rettv)
18407 {
18408     char_u	*p;
18409 
18410     p = get_tv_string(&argvars[0]);
18411     rettv->vval.v_string = vim_strsave(p);
18412     simplify_filename(rettv->vval.v_string);	/* simplify in place */
18413     rettv->v_type = VAR_STRING;
18414 }
18415 
18416 #ifdef FEAT_FLOAT
18417 /*
18418  * "sin()" function
18419  */
18420     static void
18421 f_sin(typval_T *argvars, typval_T *rettv)
18422 {
18423     float_T	f = 0.0;
18424 
18425     rettv->v_type = VAR_FLOAT;
18426     if (get_float_arg(argvars, &f) == OK)
18427 	rettv->vval.v_float = sin(f);
18428     else
18429 	rettv->vval.v_float = 0.0;
18430 }
18431 
18432 /*
18433  * "sinh()" function
18434  */
18435     static void
18436 f_sinh(typval_T *argvars, typval_T *rettv)
18437 {
18438     float_T	f = 0.0;
18439 
18440     rettv->v_type = VAR_FLOAT;
18441     if (get_float_arg(argvars, &f) == OK)
18442 	rettv->vval.v_float = sinh(f);
18443     else
18444 	rettv->vval.v_float = 0.0;
18445 }
18446 #endif
18447 
18448 static int
18449 #ifdef __BORLANDC__
18450     _RTLENTRYF
18451 #endif
18452 	item_compare(const void *s1, const void *s2);
18453 static int
18454 #ifdef __BORLANDC__
18455     _RTLENTRYF
18456 #endif
18457 	item_compare2(const void *s1, const void *s2);
18458 
18459 /* struct used in the array that's given to qsort() */
18460 typedef struct
18461 {
18462     listitem_T	*item;
18463     int		idx;
18464 } sortItem_T;
18465 
18466 /* struct storing information about current sort */
18467 typedef struct
18468 {
18469     int		item_compare_ic;
18470     int		item_compare_numeric;
18471     int		item_compare_numbers;
18472 #ifdef FEAT_FLOAT
18473     int		item_compare_float;
18474 #endif
18475     char_u	*item_compare_func;
18476     partial_T	*item_compare_partial;
18477     dict_T	*item_compare_selfdict;
18478     int		item_compare_func_err;
18479     int		item_compare_keep_zero;
18480 } sortinfo_T;
18481 static sortinfo_T	*sortinfo = NULL;
18482 static void	do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort);
18483 #define ITEM_COMPARE_FAIL 999
18484 
18485 /*
18486  * Compare functions for f_sort() and f_uniq() below.
18487  */
18488     static int
18489 #ifdef __BORLANDC__
18490 _RTLENTRYF
18491 #endif
18492 item_compare(const void *s1, const void *s2)
18493 {
18494     sortItem_T  *si1, *si2;
18495     typval_T	*tv1, *tv2;
18496     char_u	*p1, *p2;
18497     char_u	*tofree1 = NULL, *tofree2 = NULL;
18498     int		res;
18499     char_u	numbuf1[NUMBUFLEN];
18500     char_u	numbuf2[NUMBUFLEN];
18501 
18502     si1 = (sortItem_T *)s1;
18503     si2 = (sortItem_T *)s2;
18504     tv1 = &si1->item->li_tv;
18505     tv2 = &si2->item->li_tv;
18506 
18507     if (sortinfo->item_compare_numbers)
18508     {
18509 	long	v1 = get_tv_number(tv1);
18510 	long	v2 = get_tv_number(tv2);
18511 
18512 	return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
18513     }
18514 
18515 #ifdef FEAT_FLOAT
18516     if (sortinfo->item_compare_float)
18517     {
18518 	float_T	v1 = get_tv_float(tv1);
18519 	float_T	v2 = get_tv_float(tv2);
18520 
18521 	return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
18522     }
18523 #endif
18524 
18525     /* tv2string() puts quotes around a string and allocates memory.  Don't do
18526      * that for string variables. Use a single quote when comparing with a
18527      * non-string to do what the docs promise. */
18528     if (tv1->v_type == VAR_STRING)
18529     {
18530 	if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric)
18531 	    p1 = (char_u *)"'";
18532 	else
18533 	    p1 = tv1->vval.v_string;
18534     }
18535     else
18536 	p1 = tv2string(tv1, &tofree1, numbuf1, 0);
18537     if (tv2->v_type == VAR_STRING)
18538     {
18539 	if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric)
18540 	    p2 = (char_u *)"'";
18541 	else
18542 	    p2 = tv2->vval.v_string;
18543     }
18544     else
18545 	p2 = tv2string(tv2, &tofree2, numbuf2, 0);
18546     if (p1 == NULL)
18547 	p1 = (char_u *)"";
18548     if (p2 == NULL)
18549 	p2 = (char_u *)"";
18550     if (!sortinfo->item_compare_numeric)
18551     {
18552 	if (sortinfo->item_compare_ic)
18553 	    res = STRICMP(p1, p2);
18554 	else
18555 	    res = STRCMP(p1, p2);
18556     }
18557     else
18558     {
18559 	double n1, n2;
18560 	n1 = strtod((char *)p1, (char **)&p1);
18561 	n2 = strtod((char *)p2, (char **)&p2);
18562 	res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1;
18563     }
18564 
18565     /* When the result would be zero, compare the item indexes.  Makes the
18566      * sort stable. */
18567     if (res == 0 && !sortinfo->item_compare_keep_zero)
18568 	res = si1->idx > si2->idx ? 1 : -1;
18569 
18570     vim_free(tofree1);
18571     vim_free(tofree2);
18572     return res;
18573 }
18574 
18575     static int
18576 #ifdef __BORLANDC__
18577 _RTLENTRYF
18578 #endif
18579 item_compare2(const void *s1, const void *s2)
18580 {
18581     sortItem_T  *si1, *si2;
18582     int		res;
18583     typval_T	rettv;
18584     typval_T	argv[3];
18585     int		dummy;
18586     char_u	*func_name;
18587     partial_T	*partial = sortinfo->item_compare_partial;
18588 
18589     /* shortcut after failure in previous call; compare all items equal */
18590     if (sortinfo->item_compare_func_err)
18591 	return 0;
18592 
18593     si1 = (sortItem_T *)s1;
18594     si2 = (sortItem_T *)s2;
18595 
18596     if (partial == NULL)
18597 	func_name = sortinfo->item_compare_func;
18598     else
18599 	func_name = partial->pt_name;
18600 
18601     /* Copy the values.  This is needed to be able to set v_lock to VAR_FIXED
18602      * in the copy without changing the original list items. */
18603     copy_tv(&si1->item->li_tv, &argv[0]);
18604     copy_tv(&si2->item->li_tv, &argv[1]);
18605 
18606     rettv.v_type = VAR_UNKNOWN;		/* clear_tv() uses this */
18607     res = call_func(func_name, (int)STRLEN(func_name),
18608 				 &rettv, 2, argv, 0L, 0L, &dummy, TRUE,
18609 				 partial, sortinfo->item_compare_selfdict);
18610     clear_tv(&argv[0]);
18611     clear_tv(&argv[1]);
18612 
18613     if (res == FAIL)
18614 	res = ITEM_COMPARE_FAIL;
18615     else
18616 	res = get_tv_number_chk(&rettv, &sortinfo->item_compare_func_err);
18617     if (sortinfo->item_compare_func_err)
18618 	res = ITEM_COMPARE_FAIL;  /* return value has wrong type */
18619     clear_tv(&rettv);
18620 
18621     /* When the result would be zero, compare the pointers themselves.  Makes
18622      * the sort stable. */
18623     if (res == 0 && !sortinfo->item_compare_keep_zero)
18624 	res = si1->idx > si2->idx ? 1 : -1;
18625 
18626     return res;
18627 }
18628 
18629 /*
18630  * "sort({list})" function
18631  */
18632     static void
18633 do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort)
18634 {
18635     list_T	*l;
18636     listitem_T	*li;
18637     sortItem_T	*ptrs;
18638     sortinfo_T	*old_sortinfo;
18639     sortinfo_T	info;
18640     long	len;
18641     long	i;
18642 
18643     /* Pointer to current info struct used in compare function. Save and
18644      * restore the current one for nested calls. */
18645     old_sortinfo = sortinfo;
18646     sortinfo = &info;
18647 
18648     if (argvars[0].v_type != VAR_LIST)
18649 	EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
18650     else
18651     {
18652 	l = argvars[0].vval.v_list;
18653 	if (l == NULL || tv_check_lock(l->lv_lock,
18654 	     (char_u *)(sort ? N_("sort() argument") : N_("uniq() argument")),
18655 									TRUE))
18656 	    goto theend;
18657 	rettv->vval.v_list = l;
18658 	rettv->v_type = VAR_LIST;
18659 	++l->lv_refcount;
18660 
18661 	len = list_len(l);
18662 	if (len <= 1)
18663 	    goto theend;	/* short list sorts pretty quickly */
18664 
18665 	info.item_compare_ic = FALSE;
18666 	info.item_compare_numeric = FALSE;
18667 	info.item_compare_numbers = FALSE;
18668 #ifdef FEAT_FLOAT
18669 	info.item_compare_float = FALSE;
18670 #endif
18671 	info.item_compare_func = NULL;
18672 	info.item_compare_partial = NULL;
18673 	info.item_compare_selfdict = NULL;
18674 	if (argvars[1].v_type != VAR_UNKNOWN)
18675 	{
18676 	    /* optional second argument: {func} */
18677 	    if (argvars[1].v_type == VAR_FUNC)
18678 		info.item_compare_func = argvars[1].vval.v_string;
18679 	    else if (argvars[1].v_type == VAR_PARTIAL)
18680 		info.item_compare_partial = argvars[1].vval.v_partial;
18681 	    else
18682 	    {
18683 		int	    error = FALSE;
18684 
18685 		i = get_tv_number_chk(&argvars[1], &error);
18686 		if (error)
18687 		    goto theend;	/* type error; errmsg already given */
18688 		if (i == 1)
18689 		    info.item_compare_ic = TRUE;
18690 		else if (argvars[1].v_type != VAR_NUMBER)
18691 		    info.item_compare_func = get_tv_string(&argvars[1]);
18692 		else if (i != 0)
18693 		{
18694 		    EMSG(_(e_invarg));
18695 		    goto theend;
18696 		}
18697 		if (info.item_compare_func != NULL)
18698 		{
18699 		    if (*info.item_compare_func == NUL)
18700 		    {
18701 			/* empty string means default sort */
18702 			info.item_compare_func = NULL;
18703 		    }
18704 		    else if (STRCMP(info.item_compare_func, "n") == 0)
18705 		    {
18706 			info.item_compare_func = NULL;
18707 			info.item_compare_numeric = TRUE;
18708 		    }
18709 		    else if (STRCMP(info.item_compare_func, "N") == 0)
18710 		    {
18711 			info.item_compare_func = NULL;
18712 			info.item_compare_numbers = TRUE;
18713 		    }
18714 #ifdef FEAT_FLOAT
18715 		    else if (STRCMP(info.item_compare_func, "f") == 0)
18716 		    {
18717 			info.item_compare_func = NULL;
18718 			info.item_compare_float = TRUE;
18719 		    }
18720 #endif
18721 		    else if (STRCMP(info.item_compare_func, "i") == 0)
18722 		    {
18723 			info.item_compare_func = NULL;
18724 			info.item_compare_ic = TRUE;
18725 		    }
18726 		}
18727 	    }
18728 
18729 	    if (argvars[2].v_type != VAR_UNKNOWN)
18730 	    {
18731 		/* optional third argument: {dict} */
18732 		if (argvars[2].v_type != VAR_DICT)
18733 		{
18734 		    EMSG(_(e_dictreq));
18735 		    goto theend;
18736 		}
18737 		info.item_compare_selfdict = argvars[2].vval.v_dict;
18738 	    }
18739 	}
18740 
18741 	/* Make an array with each entry pointing to an item in the List. */
18742 	ptrs = (sortItem_T *)alloc((int)(len * sizeof(sortItem_T)));
18743 	if (ptrs == NULL)
18744 	    goto theend;
18745 
18746 	i = 0;
18747 	if (sort)
18748 	{
18749 	    /* sort(): ptrs will be the list to sort */
18750 	    for (li = l->lv_first; li != NULL; li = li->li_next)
18751 	    {
18752 		ptrs[i].item = li;
18753 		ptrs[i].idx = i;
18754 		++i;
18755 	    }
18756 
18757 	    info.item_compare_func_err = FALSE;
18758 	    info.item_compare_keep_zero = FALSE;
18759 	    /* test the compare function */
18760 	    if ((info.item_compare_func != NULL
18761 					 || info.item_compare_partial != NULL)
18762 		    && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
18763 							 == ITEM_COMPARE_FAIL)
18764 		EMSG(_("E702: Sort compare function failed"));
18765 	    else
18766 	    {
18767 		/* Sort the array with item pointers. */
18768 		qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T),
18769 		    info.item_compare_func == NULL
18770 					  && info.item_compare_partial == NULL
18771 					       ? item_compare : item_compare2);
18772 
18773 		if (!info.item_compare_func_err)
18774 		{
18775 		    /* Clear the List and append the items in sorted order. */
18776 		    l->lv_first = l->lv_last = l->lv_idx_item = NULL;
18777 		    l->lv_len = 0;
18778 		    for (i = 0; i < len; ++i)
18779 			list_append(l, ptrs[i].item);
18780 		}
18781 	    }
18782 	}
18783 	else
18784 	{
18785 	    int	(*item_compare_func_ptr)(const void *, const void *);
18786 
18787 	    /* f_uniq(): ptrs will be a stack of items to remove */
18788 	    info.item_compare_func_err = FALSE;
18789 	    info.item_compare_keep_zero = TRUE;
18790 	    item_compare_func_ptr = info.item_compare_func != NULL
18791 					  || info.item_compare_partial != NULL
18792 					       ? item_compare2 : item_compare;
18793 
18794 	    for (li = l->lv_first; li != NULL && li->li_next != NULL;
18795 							     li = li->li_next)
18796 	    {
18797 		if (item_compare_func_ptr((void *)&li, (void *)&li->li_next)
18798 									 == 0)
18799 		    ptrs[i++].item = li;
18800 		if (info.item_compare_func_err)
18801 		{
18802 		    EMSG(_("E882: Uniq compare function failed"));
18803 		    break;
18804 		}
18805 	    }
18806 
18807 	    if (!info.item_compare_func_err)
18808 	    {
18809 		while (--i >= 0)
18810 		{
18811 		    li = ptrs[i].item->li_next;
18812 		    ptrs[i].item->li_next = li->li_next;
18813 		    if (li->li_next != NULL)
18814 			li->li_next->li_prev = ptrs[i].item;
18815 		    else
18816 			l->lv_last = ptrs[i].item;
18817 		    list_fix_watch(l, li);
18818 		    listitem_free(li);
18819 		    l->lv_len--;
18820 		}
18821 	    }
18822 	}
18823 
18824 	vim_free(ptrs);
18825     }
18826 theend:
18827     sortinfo = old_sortinfo;
18828 }
18829 
18830 /*
18831  * "sort({list})" function
18832  */
18833     static void
18834 f_sort(typval_T *argvars, typval_T *rettv)
18835 {
18836     do_sort_uniq(argvars, rettv, TRUE);
18837 }
18838 
18839 /*
18840  * "uniq({list})" function
18841  */
18842     static void
18843 f_uniq(typval_T *argvars, typval_T *rettv)
18844 {
18845     do_sort_uniq(argvars, rettv, FALSE);
18846 }
18847 
18848 /*
18849  * "soundfold({word})" function
18850  */
18851     static void
18852 f_soundfold(typval_T *argvars, typval_T *rettv)
18853 {
18854     char_u	*s;
18855 
18856     rettv->v_type = VAR_STRING;
18857     s = get_tv_string(&argvars[0]);
18858 #ifdef FEAT_SPELL
18859     rettv->vval.v_string = eval_soundfold(s);
18860 #else
18861     rettv->vval.v_string = vim_strsave(s);
18862 #endif
18863 }
18864 
18865 /*
18866  * "spellbadword()" function
18867  */
18868     static void
18869 f_spellbadword(typval_T *argvars UNUSED, typval_T *rettv)
18870 {
18871     char_u	*word = (char_u *)"";
18872     hlf_T	attr = HLF_COUNT;
18873     int		len = 0;
18874 
18875     if (rettv_list_alloc(rettv) == FAIL)
18876 	return;
18877 
18878 #ifdef FEAT_SPELL
18879     if (argvars[0].v_type == VAR_UNKNOWN)
18880     {
18881 	/* Find the start and length of the badly spelled word. */
18882 	len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr);
18883 	if (len != 0)
18884 	    word = ml_get_cursor();
18885     }
18886     else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL)
18887     {
18888 	char_u	*str = get_tv_string_chk(&argvars[0]);
18889 	int	capcol = -1;
18890 
18891 	if (str != NULL)
18892 	{
18893 	    /* Check the argument for spelling. */
18894 	    while (*str != NUL)
18895 	    {
18896 		len = spell_check(curwin, str, &attr, &capcol, FALSE);
18897 		if (attr != HLF_COUNT)
18898 		{
18899 		    word = str;
18900 		    break;
18901 		}
18902 		str += len;
18903 	    }
18904 	}
18905     }
18906 #endif
18907 
18908     list_append_string(rettv->vval.v_list, word, len);
18909     list_append_string(rettv->vval.v_list, (char_u *)(
18910 			attr == HLF_SPB ? "bad" :
18911 			attr == HLF_SPR ? "rare" :
18912 			attr == HLF_SPL ? "local" :
18913 			attr == HLF_SPC ? "caps" :
18914 			""), -1);
18915 }
18916 
18917 /*
18918  * "spellsuggest()" function
18919  */
18920     static void
18921 f_spellsuggest(typval_T *argvars UNUSED, typval_T *rettv)
18922 {
18923 #ifdef FEAT_SPELL
18924     char_u	*str;
18925     int		typeerr = FALSE;
18926     int		maxcount;
18927     garray_T	ga;
18928     int		i;
18929     listitem_T	*li;
18930     int		need_capital = FALSE;
18931 #endif
18932 
18933     if (rettv_list_alloc(rettv) == FAIL)
18934 	return;
18935 
18936 #ifdef FEAT_SPELL
18937     if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL)
18938     {
18939 	str = get_tv_string(&argvars[0]);
18940 	if (argvars[1].v_type != VAR_UNKNOWN)
18941 	{
18942 	    maxcount = get_tv_number_chk(&argvars[1], &typeerr);
18943 	    if (maxcount <= 0)
18944 		return;
18945 	    if (argvars[2].v_type != VAR_UNKNOWN)
18946 	    {
18947 		need_capital = get_tv_number_chk(&argvars[2], &typeerr);
18948 		if (typeerr)
18949 		    return;
18950 	    }
18951 	}
18952 	else
18953 	    maxcount = 25;
18954 
18955 	spell_suggest_list(&ga, str, maxcount, need_capital, FALSE);
18956 
18957 	for (i = 0; i < ga.ga_len; ++i)
18958 	{
18959 	    str = ((char_u **)ga.ga_data)[i];
18960 
18961 	    li = listitem_alloc();
18962 	    if (li == NULL)
18963 		vim_free(str);
18964 	    else
18965 	    {
18966 		li->li_tv.v_type = VAR_STRING;
18967 		li->li_tv.v_lock = 0;
18968 		li->li_tv.vval.v_string = str;
18969 		list_append(rettv->vval.v_list, li);
18970 	    }
18971 	}
18972 	ga_clear(&ga);
18973     }
18974 #endif
18975 }
18976 
18977     static void
18978 f_split(typval_T *argvars, typval_T *rettv)
18979 {
18980     char_u	*str;
18981     char_u	*end;
18982     char_u	*pat = NULL;
18983     regmatch_T	regmatch;
18984     char_u	patbuf[NUMBUFLEN];
18985     char_u	*save_cpo;
18986     int		match;
18987     colnr_T	col = 0;
18988     int		keepempty = FALSE;
18989     int		typeerr = FALSE;
18990 
18991     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
18992     save_cpo = p_cpo;
18993     p_cpo = (char_u *)"";
18994 
18995     str = get_tv_string(&argvars[0]);
18996     if (argvars[1].v_type != VAR_UNKNOWN)
18997     {
18998 	pat = get_tv_string_buf_chk(&argvars[1], patbuf);
18999 	if (pat == NULL)
19000 	    typeerr = TRUE;
19001 	if (argvars[2].v_type != VAR_UNKNOWN)
19002 	    keepempty = get_tv_number_chk(&argvars[2], &typeerr);
19003     }
19004     if (pat == NULL || *pat == NUL)
19005 	pat = (char_u *)"[\\x01- ]\\+";
19006 
19007     if (rettv_list_alloc(rettv) == FAIL)
19008 	return;
19009     if (typeerr)
19010 	return;
19011 
19012     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
19013     if (regmatch.regprog != NULL)
19014     {
19015 	regmatch.rm_ic = FALSE;
19016 	while (*str != NUL || keepempty)
19017 	{
19018 	    if (*str == NUL)
19019 		match = FALSE;	/* empty item at the end */
19020 	    else
19021 		match = vim_regexec_nl(&regmatch, str, col);
19022 	    if (match)
19023 		end = regmatch.startp[0];
19024 	    else
19025 		end = str + STRLEN(str);
19026 	    if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0
19027 			   && *str != NUL && match && end < regmatch.endp[0]))
19028 	    {
19029 		if (list_append_string(rettv->vval.v_list, str,
19030 						    (int)(end - str)) == FAIL)
19031 		    break;
19032 	    }
19033 	    if (!match)
19034 		break;
19035 	    /* Advance to just after the match. */
19036 	    if (regmatch.endp[0] > str)
19037 		col = 0;
19038 	    else
19039 	    {
19040 		/* Don't get stuck at the same match. */
19041 #ifdef FEAT_MBYTE
19042 		col = (*mb_ptr2len)(regmatch.endp[0]);
19043 #else
19044 		col = 1;
19045 #endif
19046 	    }
19047 	    str = regmatch.endp[0];
19048 	}
19049 
19050 	vim_regfree(regmatch.regprog);
19051     }
19052 
19053     p_cpo = save_cpo;
19054 }
19055 
19056 #ifdef FEAT_FLOAT
19057 /*
19058  * "sqrt()" function
19059  */
19060     static void
19061 f_sqrt(typval_T *argvars, typval_T *rettv)
19062 {
19063     float_T	f = 0.0;
19064 
19065     rettv->v_type = VAR_FLOAT;
19066     if (get_float_arg(argvars, &f) == OK)
19067 	rettv->vval.v_float = sqrt(f);
19068     else
19069 	rettv->vval.v_float = 0.0;
19070 }
19071 
19072 /*
19073  * "str2float()" function
19074  */
19075     static void
19076 f_str2float(typval_T *argvars, typval_T *rettv)
19077 {
19078     char_u *p = skipwhite(get_tv_string(&argvars[0]));
19079 
19080     if (*p == '+')
19081 	p = skipwhite(p + 1);
19082     (void)string2float(p, &rettv->vval.v_float);
19083     rettv->v_type = VAR_FLOAT;
19084 }
19085 #endif
19086 
19087 /*
19088  * "str2nr()" function
19089  */
19090     static void
19091 f_str2nr(typval_T *argvars, typval_T *rettv)
19092 {
19093     int		base = 10;
19094     char_u	*p;
19095     long	n;
19096     int		what;
19097 
19098     if (argvars[1].v_type != VAR_UNKNOWN)
19099     {
19100 	base = get_tv_number(&argvars[1]);
19101 	if (base != 2 && base != 8 && base != 10 && base != 16)
19102 	{
19103 	    EMSG(_(e_invarg));
19104 	    return;
19105 	}
19106     }
19107 
19108     p = skipwhite(get_tv_string(&argvars[0]));
19109     if (*p == '+')
19110 	p = skipwhite(p + 1);
19111     switch (base)
19112     {
19113 	case 2: what = STR2NR_BIN + STR2NR_FORCE; break;
19114 	case 8: what = STR2NR_OCT + STR2NR_FORCE; break;
19115 	case 16: what = STR2NR_HEX + STR2NR_FORCE; break;
19116 	default: what = 0;
19117     }
19118     vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
19119     rettv->vval.v_number = n;
19120 }
19121 
19122 #ifdef HAVE_STRFTIME
19123 /*
19124  * "strftime({format}[, {time}])" function
19125  */
19126     static void
19127 f_strftime(typval_T *argvars, typval_T *rettv)
19128 {
19129     char_u	result_buf[256];
19130     struct tm	*curtime;
19131     time_t	seconds;
19132     char_u	*p;
19133 
19134     rettv->v_type = VAR_STRING;
19135 
19136     p = get_tv_string(&argvars[0]);
19137     if (argvars[1].v_type == VAR_UNKNOWN)
19138 	seconds = time(NULL);
19139     else
19140 	seconds = (time_t)get_tv_number(&argvars[1]);
19141     curtime = localtime(&seconds);
19142     /* MSVC returns NULL for an invalid value of seconds. */
19143     if (curtime == NULL)
19144 	rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
19145     else
19146     {
19147 # ifdef FEAT_MBYTE
19148 	vimconv_T   conv;
19149 	char_u	    *enc;
19150 
19151 	conv.vc_type = CONV_NONE;
19152 	enc = enc_locale();
19153 	convert_setup(&conv, p_enc, enc);
19154 	if (conv.vc_type != CONV_NONE)
19155 	    p = string_convert(&conv, p, NULL);
19156 # endif
19157 	if (p != NULL)
19158 	    (void)strftime((char *)result_buf, sizeof(result_buf),
19159 							  (char *)p, curtime);
19160 	else
19161 	    result_buf[0] = NUL;
19162 
19163 # ifdef FEAT_MBYTE
19164 	if (conv.vc_type != CONV_NONE)
19165 	    vim_free(p);
19166 	convert_setup(&conv, enc, p_enc);
19167 	if (conv.vc_type != CONV_NONE)
19168 	    rettv->vval.v_string = string_convert(&conv, result_buf, NULL);
19169 	else
19170 # endif
19171 	    rettv->vval.v_string = vim_strsave(result_buf);
19172 
19173 # ifdef FEAT_MBYTE
19174 	/* Release conversion descriptors */
19175 	convert_setup(&conv, NULL, NULL);
19176 	vim_free(enc);
19177 # endif
19178     }
19179 }
19180 #endif
19181 
19182 /*
19183  * "stridx()" function
19184  */
19185     static void
19186 f_stridx(typval_T *argvars, typval_T *rettv)
19187 {
19188     char_u	buf[NUMBUFLEN];
19189     char_u	*needle;
19190     char_u	*haystack;
19191     char_u	*save_haystack;
19192     char_u	*pos;
19193     int		start_idx;
19194 
19195     needle = get_tv_string_chk(&argvars[1]);
19196     save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf);
19197     rettv->vval.v_number = -1;
19198     if (needle == NULL || haystack == NULL)
19199 	return;		/* type error; errmsg already given */
19200 
19201     if (argvars[2].v_type != VAR_UNKNOWN)
19202     {
19203 	int	    error = FALSE;
19204 
19205 	start_idx = get_tv_number_chk(&argvars[2], &error);
19206 	if (error || start_idx >= (int)STRLEN(haystack))
19207 	    return;
19208 	if (start_idx >= 0)
19209 	    haystack += start_idx;
19210     }
19211 
19212     pos	= (char_u *)strstr((char *)haystack, (char *)needle);
19213     if (pos != NULL)
19214 	rettv->vval.v_number = (varnumber_T)(pos - save_haystack);
19215 }
19216 
19217 /*
19218  * "string()" function
19219  */
19220     static void
19221 f_string(typval_T *argvars, typval_T *rettv)
19222 {
19223     char_u	*tofree;
19224     char_u	numbuf[NUMBUFLEN];
19225 
19226     rettv->v_type = VAR_STRING;
19227     rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
19228     /* Make a copy if we have a value but it's not in allocated memory. */
19229     if (rettv->vval.v_string != NULL && tofree == NULL)
19230 	rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
19231 }
19232 
19233 /*
19234  * "strlen()" function
19235  */
19236     static void
19237 f_strlen(typval_T *argvars, typval_T *rettv)
19238 {
19239     rettv->vval.v_number = (varnumber_T)(STRLEN(
19240 					      get_tv_string(&argvars[0])));
19241 }
19242 
19243 /*
19244  * "strchars()" function
19245  */
19246     static void
19247 f_strchars(typval_T *argvars, typval_T *rettv)
19248 {
19249     char_u		*s = get_tv_string(&argvars[0]);
19250     int			skipcc = 0;
19251 #ifdef FEAT_MBYTE
19252     varnumber_T		len = 0;
19253     int			(*func_mb_ptr2char_adv)(char_u **pp);
19254 #endif
19255 
19256     if (argvars[1].v_type != VAR_UNKNOWN)
19257 	skipcc = get_tv_number_chk(&argvars[1], NULL);
19258     if (skipcc < 0 || skipcc > 1)
19259 	EMSG(_(e_invarg));
19260     else
19261     {
19262 #ifdef FEAT_MBYTE
19263 	func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
19264 	while (*s != NUL)
19265 	{
19266 	    func_mb_ptr2char_adv(&s);
19267 	    ++len;
19268 	}
19269 	rettv->vval.v_number = len;
19270 #else
19271 	rettv->vval.v_number = (varnumber_T)(STRLEN(s));
19272 #endif
19273     }
19274 }
19275 
19276 /*
19277  * "strdisplaywidth()" function
19278  */
19279     static void
19280 f_strdisplaywidth(typval_T *argvars, typval_T *rettv)
19281 {
19282     char_u	*s = get_tv_string(&argvars[0]);
19283     int		col = 0;
19284 
19285     if (argvars[1].v_type != VAR_UNKNOWN)
19286 	col = get_tv_number(&argvars[1]);
19287 
19288     rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col);
19289 }
19290 
19291 /*
19292  * "strwidth()" function
19293  */
19294     static void
19295 f_strwidth(typval_T *argvars, typval_T *rettv)
19296 {
19297     char_u	*s = get_tv_string(&argvars[0]);
19298 
19299     rettv->vval.v_number = (varnumber_T)(
19300 #ifdef FEAT_MBYTE
19301 	    mb_string2cells(s, -1)
19302 #else
19303 	    STRLEN(s)
19304 #endif
19305 	    );
19306 }
19307 
19308 /*
19309  * "strpart()" function
19310  */
19311     static void
19312 f_strpart(typval_T *argvars, typval_T *rettv)
19313 {
19314     char_u	*p;
19315     int		n;
19316     int		len;
19317     int		slen;
19318     int		error = FALSE;
19319 
19320     p = get_tv_string(&argvars[0]);
19321     slen = (int)STRLEN(p);
19322 
19323     n = get_tv_number_chk(&argvars[1], &error);
19324     if (error)
19325 	len = 0;
19326     else if (argvars[2].v_type != VAR_UNKNOWN)
19327 	len = get_tv_number(&argvars[2]);
19328     else
19329 	len = slen - n;	    /* default len: all bytes that are available. */
19330 
19331     /*
19332      * Only return the overlap between the specified part and the actual
19333      * string.
19334      */
19335     if (n < 0)
19336     {
19337 	len += n;
19338 	n = 0;
19339     }
19340     else if (n > slen)
19341 	n = slen;
19342     if (len < 0)
19343 	len = 0;
19344     else if (n + len > slen)
19345 	len = slen - n;
19346 
19347     rettv->v_type = VAR_STRING;
19348     rettv->vval.v_string = vim_strnsave(p + n, len);
19349 }
19350 
19351 /*
19352  * "strridx()" function
19353  */
19354     static void
19355 f_strridx(typval_T *argvars, typval_T *rettv)
19356 {
19357     char_u	buf[NUMBUFLEN];
19358     char_u	*needle;
19359     char_u	*haystack;
19360     char_u	*rest;
19361     char_u	*lastmatch = NULL;
19362     int		haystack_len, end_idx;
19363 
19364     needle = get_tv_string_chk(&argvars[1]);
19365     haystack = get_tv_string_buf_chk(&argvars[0], buf);
19366 
19367     rettv->vval.v_number = -1;
19368     if (needle == NULL || haystack == NULL)
19369 	return;		/* type error; errmsg already given */
19370 
19371     haystack_len = (int)STRLEN(haystack);
19372     if (argvars[2].v_type != VAR_UNKNOWN)
19373     {
19374 	/* Third argument: upper limit for index */
19375 	end_idx = get_tv_number_chk(&argvars[2], NULL);
19376 	if (end_idx < 0)
19377 	    return;	/* can never find a match */
19378     }
19379     else
19380 	end_idx = haystack_len;
19381 
19382     if (*needle == NUL)
19383     {
19384 	/* Empty string matches past the end. */
19385 	lastmatch = haystack + end_idx;
19386     }
19387     else
19388     {
19389 	for (rest = haystack; *rest != '\0'; ++rest)
19390 	{
19391 	    rest = (char_u *)strstr((char *)rest, (char *)needle);
19392 	    if (rest == NULL || rest > haystack + end_idx)
19393 		break;
19394 	    lastmatch = rest;
19395 	}
19396     }
19397 
19398     if (lastmatch == NULL)
19399 	rettv->vval.v_number = -1;
19400     else
19401 	rettv->vval.v_number = (varnumber_T)(lastmatch - haystack);
19402 }
19403 
19404 /*
19405  * "strtrans()" function
19406  */
19407     static void
19408 f_strtrans(typval_T *argvars, typval_T *rettv)
19409 {
19410     rettv->v_type = VAR_STRING;
19411     rettv->vval.v_string = transstr(get_tv_string(&argvars[0]));
19412 }
19413 
19414 /*
19415  * "submatch()" function
19416  */
19417     static void
19418 f_submatch(typval_T *argvars, typval_T *rettv)
19419 {
19420     int		error = FALSE;
19421     int		no;
19422     int		retList = 0;
19423 
19424     no = (int)get_tv_number_chk(&argvars[0], &error);
19425     if (error)
19426 	return;
19427     error = FALSE;
19428     if (argvars[1].v_type != VAR_UNKNOWN)
19429 	retList = get_tv_number_chk(&argvars[1], &error);
19430     if (error)
19431 	return;
19432 
19433     if (retList == 0)
19434     {
19435 	rettv->v_type = VAR_STRING;
19436 	rettv->vval.v_string = reg_submatch(no);
19437     }
19438     else
19439     {
19440 	rettv->v_type = VAR_LIST;
19441 	rettv->vval.v_list = reg_submatch_list(no);
19442     }
19443 }
19444 
19445 /*
19446  * "substitute()" function
19447  */
19448     static void
19449 f_substitute(typval_T *argvars, typval_T *rettv)
19450 {
19451     char_u	patbuf[NUMBUFLEN];
19452     char_u	subbuf[NUMBUFLEN];
19453     char_u	flagsbuf[NUMBUFLEN];
19454 
19455     char_u	*str = get_tv_string_chk(&argvars[0]);
19456     char_u	*pat = get_tv_string_buf_chk(&argvars[1], patbuf);
19457     char_u	*sub = get_tv_string_buf_chk(&argvars[2], subbuf);
19458     char_u	*flg = get_tv_string_buf_chk(&argvars[3], flagsbuf);
19459 
19460     rettv->v_type = VAR_STRING;
19461     if (str == NULL || pat == NULL || sub == NULL || flg == NULL)
19462 	rettv->vval.v_string = NULL;
19463     else
19464 	rettv->vval.v_string = do_string_sub(str, pat, sub, flg);
19465 }
19466 
19467 /*
19468  * "synID(lnum, col, trans)" function
19469  */
19470     static void
19471 f_synID(typval_T *argvars UNUSED, typval_T *rettv)
19472 {
19473     int		id = 0;
19474 #ifdef FEAT_SYN_HL
19475     long	lnum;
19476     long	col;
19477     int		trans;
19478     int		transerr = FALSE;
19479 
19480     lnum = get_tv_lnum(argvars);		/* -1 on type error */
19481     col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
19482     trans = get_tv_number_chk(&argvars[2], &transerr);
19483 
19484     if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
19485 	    && col >= 0 && col < (long)STRLEN(ml_get(lnum)))
19486 	id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE);
19487 #endif
19488 
19489     rettv->vval.v_number = id;
19490 }
19491 
19492 /*
19493  * "synIDattr(id, what [, mode])" function
19494  */
19495     static void
19496 f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv)
19497 {
19498     char_u	*p = NULL;
19499 #ifdef FEAT_SYN_HL
19500     int		id;
19501     char_u	*what;
19502     char_u	*mode;
19503     char_u	modebuf[NUMBUFLEN];
19504     int		modec;
19505 
19506     id = get_tv_number(&argvars[0]);
19507     what = get_tv_string(&argvars[1]);
19508     if (argvars[2].v_type != VAR_UNKNOWN)
19509     {
19510 	mode = get_tv_string_buf(&argvars[2], modebuf);
19511 	modec = TOLOWER_ASC(mode[0]);
19512 	if (modec != 't' && modec != 'c' && modec != 'g')
19513 	    modec = 0;	/* replace invalid with current */
19514     }
19515     else
19516     {
19517 #ifdef FEAT_GUI
19518 	if (gui.in_use)
19519 	    modec = 'g';
19520 	else
19521 #endif
19522 	    if (t_colors > 1)
19523 	    modec = 'c';
19524 	else
19525 	    modec = 't';
19526     }
19527 
19528 
19529     switch (TOLOWER_ASC(what[0]))
19530     {
19531 	case 'b':
19532 		if (TOLOWER_ASC(what[1]) == 'g')	/* bg[#] */
19533 		    p = highlight_color(id, what, modec);
19534 		else					/* bold */
19535 		    p = highlight_has_attr(id, HL_BOLD, modec);
19536 		break;
19537 
19538 	case 'f':					/* fg[#] or font */
19539 		p = highlight_color(id, what, modec);
19540 		break;
19541 
19542 	case 'i':
19543 		if (TOLOWER_ASC(what[1]) == 'n')	/* inverse */
19544 		    p = highlight_has_attr(id, HL_INVERSE, modec);
19545 		else					/* italic */
19546 		    p = highlight_has_attr(id, HL_ITALIC, modec);
19547 		break;
19548 
19549 	case 'n':					/* name */
19550 		p = get_highlight_name(NULL, id - 1);
19551 		break;
19552 
19553 	case 'r':					/* reverse */
19554 		p = highlight_has_attr(id, HL_INVERSE, modec);
19555 		break;
19556 
19557 	case 's':
19558 		if (TOLOWER_ASC(what[1]) == 'p')	/* sp[#] */
19559 		    p = highlight_color(id, what, modec);
19560 		else					/* standout */
19561 		    p = highlight_has_attr(id, HL_STANDOUT, modec);
19562 		break;
19563 
19564 	case 'u':
19565 		if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c')
19566 							/* underline */
19567 		    p = highlight_has_attr(id, HL_UNDERLINE, modec);
19568 		else
19569 							/* undercurl */
19570 		    p = highlight_has_attr(id, HL_UNDERCURL, modec);
19571 		break;
19572     }
19573 
19574     if (p != NULL)
19575 	p = vim_strsave(p);
19576 #endif
19577     rettv->v_type = VAR_STRING;
19578     rettv->vval.v_string = p;
19579 }
19580 
19581 /*
19582  * "synIDtrans(id)" function
19583  */
19584     static void
19585 f_synIDtrans(typval_T *argvars UNUSED, typval_T *rettv)
19586 {
19587     int		id;
19588 
19589 #ifdef FEAT_SYN_HL
19590     id = get_tv_number(&argvars[0]);
19591 
19592     if (id > 0)
19593 	id = syn_get_final_id(id);
19594     else
19595 #endif
19596 	id = 0;
19597 
19598     rettv->vval.v_number = id;
19599 }
19600 
19601 /*
19602  * "synconcealed(lnum, col)" function
19603  */
19604     static void
19605 f_synconcealed(typval_T *argvars UNUSED, typval_T *rettv)
19606 {
19607 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL)
19608     long	lnum;
19609     long	col;
19610     int		syntax_flags = 0;
19611     int		cchar;
19612     int		matchid = 0;
19613     char_u	str[NUMBUFLEN];
19614 #endif
19615 
19616     rettv->v_type = VAR_LIST;
19617     rettv->vval.v_list = NULL;
19618 
19619 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL)
19620     lnum = get_tv_lnum(argvars);		/* -1 on type error */
19621     col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
19622 
19623     vim_memset(str, NUL, sizeof(str));
19624 
19625     if (rettv_list_alloc(rettv) != FAIL)
19626     {
19627 	if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
19628 	    && col >= 0 && col <= (long)STRLEN(ml_get(lnum))
19629 	    && curwin->w_p_cole > 0)
19630 	{
19631 	    (void)syn_get_id(curwin, lnum, col, FALSE, NULL, FALSE);
19632 	    syntax_flags = get_syntax_info(&matchid);
19633 
19634 	    /* get the conceal character */
19635 	    if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3)
19636 	    {
19637 		cchar = syn_get_sub_char();
19638 		if (cchar == NUL && curwin->w_p_cole == 1 && lcs_conceal != NUL)
19639 		    cchar = lcs_conceal;
19640 		if (cchar != NUL)
19641 		{
19642 # ifdef FEAT_MBYTE
19643 		    if (has_mbyte)
19644 			(*mb_char2bytes)(cchar, str);
19645 		    else
19646 # endif
19647 			str[0] = cchar;
19648 		}
19649 	    }
19650 	}
19651 
19652 	list_append_number(rettv->vval.v_list,
19653 					    (syntax_flags & HL_CONCEAL) != 0);
19654 	/* -1 to auto-determine strlen */
19655 	list_append_string(rettv->vval.v_list, str, -1);
19656 	list_append_number(rettv->vval.v_list, matchid);
19657     }
19658 #endif
19659 }
19660 
19661 /*
19662  * "synstack(lnum, col)" function
19663  */
19664     static void
19665 f_synstack(typval_T *argvars UNUSED, typval_T *rettv)
19666 {
19667 #ifdef FEAT_SYN_HL
19668     long	lnum;
19669     long	col;
19670     int		i;
19671     int		id;
19672 #endif
19673 
19674     rettv->v_type = VAR_LIST;
19675     rettv->vval.v_list = NULL;
19676 
19677 #ifdef FEAT_SYN_HL
19678     lnum = get_tv_lnum(argvars);		/* -1 on type error */
19679     col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
19680 
19681     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
19682 	    && col >= 0 && col <= (long)STRLEN(ml_get(lnum))
19683 	    && rettv_list_alloc(rettv) != FAIL)
19684     {
19685 	(void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE);
19686 	for (i = 0; ; ++i)
19687 	{
19688 	    id = syn_get_stack_item(i);
19689 	    if (id < 0)
19690 		break;
19691 	    if (list_append_number(rettv->vval.v_list, id) == FAIL)
19692 		break;
19693 	}
19694     }
19695 #endif
19696 }
19697 
19698     static void
19699 get_cmd_output_as_rettv(
19700     typval_T	*argvars,
19701     typval_T	*rettv,
19702     int		retlist)
19703 {
19704     char_u	*res = NULL;
19705     char_u	*p;
19706     char_u	*infile = NULL;
19707     char_u	buf[NUMBUFLEN];
19708     int		err = FALSE;
19709     FILE	*fd;
19710     list_T	*list = NULL;
19711     int		flags = SHELL_SILENT;
19712 
19713     rettv->v_type = VAR_STRING;
19714     rettv->vval.v_string = NULL;
19715     if (check_restricted() || check_secure())
19716 	goto errret;
19717 
19718     if (argvars[1].v_type != VAR_UNKNOWN)
19719     {
19720 	/*
19721 	 * Write the string to a temp file, to be used for input of the shell
19722 	 * command.
19723 	 */
19724 	if ((infile = vim_tempname('i', TRUE)) == NULL)
19725 	{
19726 	    EMSG(_(e_notmp));
19727 	    goto errret;
19728 	}
19729 
19730 	fd = mch_fopen((char *)infile, WRITEBIN);
19731 	if (fd == NULL)
19732 	{
19733 	    EMSG2(_(e_notopen), infile);
19734 	    goto errret;
19735 	}
19736 	if (argvars[1].v_type == VAR_LIST)
19737 	{
19738 	    if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL)
19739 		err = TRUE;
19740 	}
19741 	else
19742 	{
19743 	    size_t len;
19744 
19745 	    p = get_tv_string_buf_chk(&argvars[1], buf);
19746 	    if (p == NULL)
19747 	    {
19748 		fclose(fd);
19749 		goto errret;		/* type error; errmsg already given */
19750 	    }
19751 	    len = STRLEN(p);
19752 	    if (len > 0 && fwrite(p, len, 1, fd) != 1)
19753 		err = TRUE;
19754 	}
19755 	if (fclose(fd) != 0)
19756 	    err = TRUE;
19757 	if (err)
19758 	{
19759 	    EMSG(_("E677: Error writing temp file"));
19760 	    goto errret;
19761 	}
19762     }
19763 
19764     /* Omit SHELL_COOKED when invoked with ":silent".  Avoids that the shell
19765      * echoes typeahead, that messes up the display. */
19766     if (!msg_silent)
19767 	flags += SHELL_COOKED;
19768 
19769     if (retlist)
19770     {
19771 	int		len;
19772 	listitem_T	*li;
19773 	char_u		*s = NULL;
19774 	char_u		*start;
19775 	char_u		*end;
19776 	int		i;
19777 
19778 	res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, &len);
19779 	if (res == NULL)
19780 	    goto errret;
19781 
19782 	list = list_alloc();
19783 	if (list == NULL)
19784 	    goto errret;
19785 
19786 	for (i = 0; i < len; ++i)
19787 	{
19788 	    start = res + i;
19789 	    while (i < len && res[i] != NL)
19790 		++i;
19791 	    end = res + i;
19792 
19793 	    s = alloc((unsigned)(end - start + 1));
19794 	    if (s == NULL)
19795 		goto errret;
19796 
19797 	    for (p = s; start < end; ++p, ++start)
19798 		*p = *start == NUL ? NL : *start;
19799 	    *p = NUL;
19800 
19801 	    li = listitem_alloc();
19802 	    if (li == NULL)
19803 	    {
19804 		vim_free(s);
19805 		goto errret;
19806 	    }
19807 	    li->li_tv.v_type = VAR_STRING;
19808 	    li->li_tv.v_lock = 0;
19809 	    li->li_tv.vval.v_string = s;
19810 	    list_append(list, li);
19811 	}
19812 
19813 	++list->lv_refcount;
19814 	rettv->v_type = VAR_LIST;
19815 	rettv->vval.v_list = list;
19816 	list = NULL;
19817     }
19818     else
19819     {
19820 	res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, NULL);
19821 #ifdef USE_CR
19822 	/* translate <CR> into <NL> */
19823 	if (res != NULL)
19824 	{
19825 	    char_u	*s;
19826 
19827 	    for (s = res; *s; ++s)
19828 	    {
19829 		if (*s == CAR)
19830 		    *s = NL;
19831 	    }
19832 	}
19833 #else
19834 # ifdef USE_CRNL
19835 	/* translate <CR><NL> into <NL> */
19836 	if (res != NULL)
19837 	{
19838 	    char_u	*s, *d;
19839 
19840 	    d = res;
19841 	    for (s = res; *s; ++s)
19842 	    {
19843 		if (s[0] == CAR && s[1] == NL)
19844 		    ++s;
19845 		*d++ = *s;
19846 	    }
19847 	    *d = NUL;
19848 	}
19849 # endif
19850 #endif
19851 	rettv->vval.v_string = res;
19852 	res = NULL;
19853     }
19854 
19855 errret:
19856     if (infile != NULL)
19857     {
19858 	mch_remove(infile);
19859 	vim_free(infile);
19860     }
19861     if (res != NULL)
19862 	vim_free(res);
19863     if (list != NULL)
19864 	list_free(list, TRUE);
19865 }
19866 
19867 /*
19868  * "system()" function
19869  */
19870     static void
19871 f_system(typval_T *argvars, typval_T *rettv)
19872 {
19873     get_cmd_output_as_rettv(argvars, rettv, FALSE);
19874 }
19875 
19876 /*
19877  * "systemlist()" function
19878  */
19879     static void
19880 f_systemlist(typval_T *argvars, typval_T *rettv)
19881 {
19882     get_cmd_output_as_rettv(argvars, rettv, TRUE);
19883 }
19884 
19885 /*
19886  * "tabpagebuflist()" function
19887  */
19888     static void
19889 f_tabpagebuflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
19890 {
19891 #ifdef FEAT_WINDOWS
19892     tabpage_T	*tp;
19893     win_T	*wp = NULL;
19894 
19895     if (argvars[0].v_type == VAR_UNKNOWN)
19896 	wp = firstwin;
19897     else
19898     {
19899 	tp = find_tabpage((int)get_tv_number(&argvars[0]));
19900 	if (tp != NULL)
19901 	    wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
19902     }
19903     if (wp != NULL && rettv_list_alloc(rettv) != FAIL)
19904     {
19905 	for (; wp != NULL; wp = wp->w_next)
19906 	    if (list_append_number(rettv->vval.v_list,
19907 						wp->w_buffer->b_fnum) == FAIL)
19908 		break;
19909     }
19910 #endif
19911 }
19912 
19913 
19914 /*
19915  * "tabpagenr()" function
19916  */
19917     static void
19918 f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv)
19919 {
19920     int		nr = 1;
19921 #ifdef FEAT_WINDOWS
19922     char_u	*arg;
19923 
19924     if (argvars[0].v_type != VAR_UNKNOWN)
19925     {
19926 	arg = get_tv_string_chk(&argvars[0]);
19927 	nr = 0;
19928 	if (arg != NULL)
19929 	{
19930 	    if (STRCMP(arg, "$") == 0)
19931 		nr = tabpage_index(NULL) - 1;
19932 	    else
19933 		EMSG2(_(e_invexpr2), arg);
19934 	}
19935     }
19936     else
19937 	nr = tabpage_index(curtab);
19938 #endif
19939     rettv->vval.v_number = nr;
19940 }
19941 
19942 
19943 #ifdef FEAT_WINDOWS
19944 static int get_winnr(tabpage_T *tp, typval_T *argvar);
19945 
19946 /*
19947  * Common code for tabpagewinnr() and winnr().
19948  */
19949     static int
19950 get_winnr(tabpage_T *tp, typval_T *argvar)
19951 {
19952     win_T	*twin;
19953     int		nr = 1;
19954     win_T	*wp;
19955     char_u	*arg;
19956 
19957     twin = (tp == curtab) ? curwin : tp->tp_curwin;
19958     if (argvar->v_type != VAR_UNKNOWN)
19959     {
19960 	arg = get_tv_string_chk(argvar);
19961 	if (arg == NULL)
19962 	    nr = 0;		/* type error; errmsg already given */
19963 	else if (STRCMP(arg, "$") == 0)
19964 	    twin = (tp == curtab) ? lastwin : tp->tp_lastwin;
19965 	else if (STRCMP(arg, "#") == 0)
19966 	{
19967 	    twin = (tp == curtab) ? prevwin : tp->tp_prevwin;
19968 	    if (twin == NULL)
19969 		nr = 0;
19970 	}
19971 	else
19972 	{
19973 	    EMSG2(_(e_invexpr2), arg);
19974 	    nr = 0;
19975 	}
19976     }
19977 
19978     if (nr > 0)
19979 	for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
19980 					      wp != twin; wp = wp->w_next)
19981 	{
19982 	    if (wp == NULL)
19983 	    {
19984 		/* didn't find it in this tabpage */
19985 		nr = 0;
19986 		break;
19987 	    }
19988 	    ++nr;
19989 	}
19990     return nr;
19991 }
19992 #endif
19993 
19994 /*
19995  * "tabpagewinnr()" function
19996  */
19997     static void
19998 f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv)
19999 {
20000     int		nr = 1;
20001 #ifdef FEAT_WINDOWS
20002     tabpage_T	*tp;
20003 
20004     tp = find_tabpage((int)get_tv_number(&argvars[0]));
20005     if (tp == NULL)
20006 	nr = 0;
20007     else
20008 	nr = get_winnr(tp, &argvars[1]);
20009 #endif
20010     rettv->vval.v_number = nr;
20011 }
20012 
20013 
20014 /*
20015  * "tagfiles()" function
20016  */
20017     static void
20018 f_tagfiles(typval_T *argvars UNUSED, typval_T *rettv)
20019 {
20020     char_u	*fname;
20021     tagname_T	tn;
20022     int		first;
20023 
20024     if (rettv_list_alloc(rettv) == FAIL)
20025 	return;
20026     fname = alloc(MAXPATHL);
20027     if (fname == NULL)
20028 	return;
20029 
20030     for (first = TRUE; ; first = FALSE)
20031 	if (get_tagfname(&tn, first, fname) == FAIL
20032 		|| list_append_string(rettv->vval.v_list, fname, -1) == FAIL)
20033 	    break;
20034     tagname_free(&tn);
20035     vim_free(fname);
20036 }
20037 
20038 /*
20039  * "taglist()" function
20040  */
20041     static void
20042 f_taglist(typval_T *argvars, typval_T *rettv)
20043 {
20044     char_u  *tag_pattern;
20045 
20046     tag_pattern = get_tv_string(&argvars[0]);
20047 
20048     rettv->vval.v_number = FALSE;
20049     if (*tag_pattern == NUL)
20050 	return;
20051 
20052     if (rettv_list_alloc(rettv) == OK)
20053 	(void)get_tags(rettv->vval.v_list, tag_pattern);
20054 }
20055 
20056 /*
20057  * "tempname()" function
20058  */
20059     static void
20060 f_tempname(typval_T *argvars UNUSED, typval_T *rettv)
20061 {
20062     static int	x = 'A';
20063 
20064     rettv->v_type = VAR_STRING;
20065     rettv->vval.v_string = vim_tempname(x, FALSE);
20066 
20067     /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different
20068      * names.  Skip 'I' and 'O', they are used for shell redirection. */
20069     do
20070     {
20071 	if (x == 'Z')
20072 	    x = '0';
20073 	else if (x == '9')
20074 	    x = 'A';
20075 	else
20076 	{
20077 #ifdef EBCDIC
20078 	    if (x == 'I')
20079 		x = 'J';
20080 	    else if (x == 'R')
20081 		x = 'S';
20082 	    else
20083 #endif
20084 		++x;
20085 	}
20086     } while (x == 'I' || x == 'O');
20087 }
20088 
20089 /*
20090  * "test(list)" function: Just checking the walls...
20091  */
20092     static void
20093 f_test(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
20094 {
20095     /* Used for unit testing.  Change the code below to your liking. */
20096 #if 0
20097     listitem_T	*li;
20098     list_T	*l;
20099     char_u	*bad, *good;
20100 
20101     if (argvars[0].v_type != VAR_LIST)
20102 	return;
20103     l = argvars[0].vval.v_list;
20104     if (l == NULL)
20105 	return;
20106     li = l->lv_first;
20107     if (li == NULL)
20108 	return;
20109     bad = get_tv_string(&li->li_tv);
20110     li = li->li_next;
20111     if (li == NULL)
20112 	return;
20113     good = get_tv_string(&li->li_tv);
20114     rettv->vval.v_number = test_edit_score(bad, good);
20115 #endif
20116 }
20117 
20118 #ifdef FEAT_FLOAT
20119 /*
20120  * "tan()" function
20121  */
20122     static void
20123 f_tan(typval_T *argvars, typval_T *rettv)
20124 {
20125     float_T	f = 0.0;
20126 
20127     rettv->v_type = VAR_FLOAT;
20128     if (get_float_arg(argvars, &f) == OK)
20129 	rettv->vval.v_float = tan(f);
20130     else
20131 	rettv->vval.v_float = 0.0;
20132 }
20133 
20134 /*
20135  * "tanh()" function
20136  */
20137     static void
20138 f_tanh(typval_T *argvars, typval_T *rettv)
20139 {
20140     float_T	f = 0.0;
20141 
20142     rettv->v_type = VAR_FLOAT;
20143     if (get_float_arg(argvars, &f) == OK)
20144 	rettv->vval.v_float = tanh(f);
20145     else
20146 	rettv->vval.v_float = 0.0;
20147 }
20148 #endif
20149 
20150 #if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO)
20151 /*
20152  * Get a callback from "arg".  It can be a Funcref or a function name.
20153  * When "arg" is zero return an empty string.
20154  * Return NULL for an invalid argument.
20155  */
20156     char_u *
20157 get_callback(typval_T *arg, partial_T **pp)
20158 {
20159     if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
20160     {
20161 	*pp = arg->vval.v_partial;
20162 	return (*pp)->pt_name;
20163     }
20164     *pp = NULL;
20165     if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
20166 	return arg->vval.v_string;
20167     if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
20168 	return (char_u *)"";
20169     EMSG(_("E921: Invalid callback argument"));
20170     return NULL;
20171 }
20172 #endif
20173 
20174 #ifdef FEAT_TIMERS
20175 /*
20176  * "timer_start(time, callback [, options])" function
20177  */
20178     static void
20179 f_timer_start(typval_T *argvars, typval_T *rettv)
20180 {
20181     long    msec = get_tv_number(&argvars[0]);
20182     timer_T *timer;
20183     int	    repeat = 0;
20184     char_u  *callback;
20185     dict_T  *dict;
20186 
20187     if (argvars[2].v_type != VAR_UNKNOWN)
20188     {
20189 	if (argvars[2].v_type != VAR_DICT
20190 				   || (dict = argvars[2].vval.v_dict) == NULL)
20191 	{
20192 	    EMSG2(_(e_invarg2), get_tv_string(&argvars[2]));
20193 	    return;
20194 	}
20195 	if (dict_find(dict, (char_u *)"repeat", -1) != NULL)
20196 	    repeat = get_dict_number(dict, (char_u *)"repeat");
20197     }
20198 
20199     timer = create_timer(msec, repeat);
20200     callback = get_callback(&argvars[1], &timer->tr_partial);
20201     if (callback == NULL)
20202     {
20203 	stop_timer(timer);
20204 	rettv->vval.v_number = -1;
20205     }
20206     else
20207     {
20208 	timer->tr_callback = vim_strsave(callback);
20209 	rettv->vval.v_number = timer->tr_id;
20210     }
20211 }
20212 
20213 /*
20214  * "timer_stop(timer)" function
20215  */
20216     static void
20217 f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED)
20218 {
20219     timer_T *timer = find_timer(get_tv_number(&argvars[0]));
20220 
20221     if (timer != NULL)
20222 	stop_timer(timer);
20223 }
20224 #endif
20225 
20226 /*
20227  * "tolower(string)" function
20228  */
20229     static void
20230 f_tolower(typval_T *argvars, typval_T *rettv)
20231 {
20232     char_u	*p;
20233 
20234     p = vim_strsave(get_tv_string(&argvars[0]));
20235     rettv->v_type = VAR_STRING;
20236     rettv->vval.v_string = p;
20237 
20238     if (p != NULL)
20239 	while (*p != NUL)
20240 	{
20241 #ifdef FEAT_MBYTE
20242 	    int		l;
20243 
20244 	    if (enc_utf8)
20245 	    {
20246 		int c, lc;
20247 
20248 		c = utf_ptr2char(p);
20249 		lc = utf_tolower(c);
20250 		l = utf_ptr2len(p);
20251 		/* TODO: reallocate string when byte count changes. */
20252 		if (utf_char2len(lc) == l)
20253 		    utf_char2bytes(lc, p);
20254 		p += l;
20255 	    }
20256 	    else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
20257 		p += l;		/* skip multi-byte character */
20258 	    else
20259 #endif
20260 	    {
20261 		*p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
20262 		++p;
20263 	    }
20264 	}
20265 }
20266 
20267 /*
20268  * "toupper(string)" function
20269  */
20270     static void
20271 f_toupper(typval_T *argvars, typval_T *rettv)
20272 {
20273     rettv->v_type = VAR_STRING;
20274     rettv->vval.v_string = strup_save(get_tv_string(&argvars[0]));
20275 }
20276 
20277 /*
20278  * "tr(string, fromstr, tostr)" function
20279  */
20280     static void
20281 f_tr(typval_T *argvars, typval_T *rettv)
20282 {
20283     char_u	*in_str;
20284     char_u	*fromstr;
20285     char_u	*tostr;
20286     char_u	*p;
20287 #ifdef FEAT_MBYTE
20288     int		inlen;
20289     int		fromlen;
20290     int		tolen;
20291     int		idx;
20292     char_u	*cpstr;
20293     int		cplen;
20294     int		first = TRUE;
20295 #endif
20296     char_u	buf[NUMBUFLEN];
20297     char_u	buf2[NUMBUFLEN];
20298     garray_T	ga;
20299 
20300     in_str = get_tv_string(&argvars[0]);
20301     fromstr = get_tv_string_buf_chk(&argvars[1], buf);
20302     tostr = get_tv_string_buf_chk(&argvars[2], buf2);
20303 
20304     /* Default return value: empty string. */
20305     rettv->v_type = VAR_STRING;
20306     rettv->vval.v_string = NULL;
20307     if (fromstr == NULL || tostr == NULL)
20308 	    return;		/* type error; errmsg already given */
20309     ga_init2(&ga, (int)sizeof(char), 80);
20310 
20311 #ifdef FEAT_MBYTE
20312     if (!has_mbyte)
20313 #endif
20314 	/* not multi-byte: fromstr and tostr must be the same length */
20315 	if (STRLEN(fromstr) != STRLEN(tostr))
20316 	{
20317 #ifdef FEAT_MBYTE
20318 error:
20319 #endif
20320 	    EMSG2(_(e_invarg2), fromstr);
20321 	    ga_clear(&ga);
20322 	    return;
20323 	}
20324 
20325     /* fromstr and tostr have to contain the same number of chars */
20326     while (*in_str != NUL)
20327     {
20328 #ifdef FEAT_MBYTE
20329 	if (has_mbyte)
20330 	{
20331 	    inlen = (*mb_ptr2len)(in_str);
20332 	    cpstr = in_str;
20333 	    cplen = inlen;
20334 	    idx = 0;
20335 	    for (p = fromstr; *p != NUL; p += fromlen)
20336 	    {
20337 		fromlen = (*mb_ptr2len)(p);
20338 		if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0)
20339 		{
20340 		    for (p = tostr; *p != NUL; p += tolen)
20341 		    {
20342 			tolen = (*mb_ptr2len)(p);
20343 			if (idx-- == 0)
20344 			{
20345 			    cplen = tolen;
20346 			    cpstr = p;
20347 			    break;
20348 			}
20349 		    }
20350 		    if (*p == NUL)	/* tostr is shorter than fromstr */
20351 			goto error;
20352 		    break;
20353 		}
20354 		++idx;
20355 	    }
20356 
20357 	    if (first && cpstr == in_str)
20358 	    {
20359 		/* Check that fromstr and tostr have the same number of
20360 		 * (multi-byte) characters.  Done only once when a character
20361 		 * of in_str doesn't appear in fromstr. */
20362 		first = FALSE;
20363 		for (p = tostr; *p != NUL; p += tolen)
20364 		{
20365 		    tolen = (*mb_ptr2len)(p);
20366 		    --idx;
20367 		}
20368 		if (idx != 0)
20369 		    goto error;
20370 	    }
20371 
20372 	    (void)ga_grow(&ga, cplen);
20373 	    mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen);
20374 	    ga.ga_len += cplen;
20375 
20376 	    in_str += inlen;
20377 	}
20378 	else
20379 #endif
20380 	{
20381 	    /* When not using multi-byte chars we can do it faster. */
20382 	    p = vim_strchr(fromstr, *in_str);
20383 	    if (p != NULL)
20384 		ga_append(&ga, tostr[p - fromstr]);
20385 	    else
20386 		ga_append(&ga, *in_str);
20387 	    ++in_str;
20388 	}
20389     }
20390 
20391     /* add a terminating NUL */
20392     (void)ga_grow(&ga, 1);
20393     ga_append(&ga, NUL);
20394 
20395     rettv->vval.v_string = ga.ga_data;
20396 }
20397 
20398 #ifdef FEAT_FLOAT
20399 /*
20400  * "trunc({float})" function
20401  */
20402     static void
20403 f_trunc(typval_T *argvars, typval_T *rettv)
20404 {
20405     float_T	f = 0.0;
20406 
20407     rettv->v_type = VAR_FLOAT;
20408     if (get_float_arg(argvars, &f) == OK)
20409 	/* trunc() is not in C90, use floor() or ceil() instead. */
20410 	rettv->vval.v_float = f > 0 ? floor(f) : ceil(f);
20411     else
20412 	rettv->vval.v_float = 0.0;
20413 }
20414 #endif
20415 
20416 /*
20417  * "type(expr)" function
20418  */
20419     static void
20420 f_type(typval_T *argvars, typval_T *rettv)
20421 {
20422     int n = -1;
20423 
20424     switch (argvars[0].v_type)
20425     {
20426 	case VAR_NUMBER: n = 0; break;
20427 	case VAR_STRING: n = 1; break;
20428 	case VAR_PARTIAL:
20429 	case VAR_FUNC:   n = 2; break;
20430 	case VAR_LIST:   n = 3; break;
20431 	case VAR_DICT:   n = 4; break;
20432 	case VAR_FLOAT:  n = 5; break;
20433 	case VAR_SPECIAL:
20434 	     if (argvars[0].vval.v_number == VVAL_FALSE
20435 		     || argvars[0].vval.v_number == VVAL_TRUE)
20436 		 n = 6;
20437 	     else
20438 		 n = 7;
20439 	     break;
20440 	case VAR_JOB:     n = 8; break;
20441 	case VAR_CHANNEL: n = 9; break;
20442 	case VAR_UNKNOWN:
20443 	     EMSG2(_(e_intern2), "f_type(UNKNOWN)");
20444 	     n = -1;
20445 	     break;
20446     }
20447     rettv->vval.v_number = n;
20448 }
20449 
20450 /*
20451  * "undofile(name)" function
20452  */
20453     static void
20454 f_undofile(typval_T *argvars UNUSED, typval_T *rettv)
20455 {
20456     rettv->v_type = VAR_STRING;
20457 #ifdef FEAT_PERSISTENT_UNDO
20458     {
20459 	char_u *fname = get_tv_string(&argvars[0]);
20460 
20461 	if (*fname == NUL)
20462 	{
20463 	    /* If there is no file name there will be no undo file. */
20464 	    rettv->vval.v_string = NULL;
20465 	}
20466 	else
20467 	{
20468 	    char_u *ffname = FullName_save(fname, FALSE);
20469 
20470 	    if (ffname != NULL)
20471 		rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE);
20472 	    vim_free(ffname);
20473 	}
20474     }
20475 #else
20476     rettv->vval.v_string = NULL;
20477 #endif
20478 }
20479 
20480 /*
20481  * "undotree()" function
20482  */
20483     static void
20484 f_undotree(typval_T *argvars UNUSED, typval_T *rettv)
20485 {
20486     if (rettv_dict_alloc(rettv) == OK)
20487     {
20488 	dict_T *dict = rettv->vval.v_dict;
20489 	list_T *list;
20490 
20491 	dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL);
20492 	dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL);
20493 	dict_add_nr_str(dict, "save_last",
20494 					(long)curbuf->b_u_save_nr_last, NULL);
20495 	dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL);
20496 	dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL);
20497 	dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL);
20498 
20499 	list = list_alloc();
20500 	if (list != NULL)
20501 	{
20502 	    u_eval_tree(curbuf->b_u_oldhead, list);
20503 	    dict_add_list(dict, "entries", list);
20504 	}
20505     }
20506 }
20507 
20508 /*
20509  * "values(dict)" function
20510  */
20511     static void
20512 f_values(typval_T *argvars, typval_T *rettv)
20513 {
20514     dict_list(argvars, rettv, 1);
20515 }
20516 
20517 /*
20518  * "virtcol(string)" function
20519  */
20520     static void
20521 f_virtcol(typval_T *argvars, typval_T *rettv)
20522 {
20523     colnr_T	vcol = 0;
20524     pos_T	*fp;
20525     int		fnum = curbuf->b_fnum;
20526 
20527     fp = var2fpos(&argvars[0], FALSE, &fnum);
20528     if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
20529 						    && fnum == curbuf->b_fnum)
20530     {
20531 	getvvcol(curwin, fp, NULL, NULL, &vcol);
20532 	++vcol;
20533     }
20534 
20535     rettv->vval.v_number = vcol;
20536 }
20537 
20538 /*
20539  * "visualmode()" function
20540  */
20541     static void
20542 f_visualmode(typval_T *argvars, typval_T *rettv)
20543 {
20544     char_u	str[2];
20545 
20546     rettv->v_type = VAR_STRING;
20547     str[0] = curbuf->b_visual_mode_eval;
20548     str[1] = NUL;
20549     rettv->vval.v_string = vim_strsave(str);
20550 
20551     /* A non-zero number or non-empty string argument: reset mode. */
20552     if (non_zero_arg(&argvars[0]))
20553 	curbuf->b_visual_mode_eval = NUL;
20554 }
20555 
20556 /*
20557  * "wildmenumode()" function
20558  */
20559     static void
20560 f_wildmenumode(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
20561 {
20562 #ifdef FEAT_WILDMENU
20563     if (wild_menu_showing)
20564 	rettv->vval.v_number = 1;
20565 #endif
20566 }
20567 
20568 /*
20569  * "winbufnr(nr)" function
20570  */
20571     static void
20572 f_winbufnr(typval_T *argvars, typval_T *rettv)
20573 {
20574     win_T	*wp;
20575 
20576     wp = find_win_by_nr(&argvars[0], NULL);
20577     if (wp == NULL)
20578 	rettv->vval.v_number = -1;
20579     else
20580 	rettv->vval.v_number = wp->w_buffer->b_fnum;
20581 }
20582 
20583 /*
20584  * "wincol()" function
20585  */
20586     static void
20587 f_wincol(typval_T *argvars UNUSED, typval_T *rettv)
20588 {
20589     validate_cursor();
20590     rettv->vval.v_number = curwin->w_wcol + 1;
20591 }
20592 
20593 /*
20594  * "winheight(nr)" function
20595  */
20596     static void
20597 f_winheight(typval_T *argvars, typval_T *rettv)
20598 {
20599     win_T	*wp;
20600 
20601     wp = find_win_by_nr(&argvars[0], NULL);
20602     if (wp == NULL)
20603 	rettv->vval.v_number = -1;
20604     else
20605 	rettv->vval.v_number = wp->w_height;
20606 }
20607 
20608 /*
20609  * "winline()" function
20610  */
20611     static void
20612 f_winline(typval_T *argvars UNUSED, typval_T *rettv)
20613 {
20614     validate_cursor();
20615     rettv->vval.v_number = curwin->w_wrow + 1;
20616 }
20617 
20618 /*
20619  * "winnr()" function
20620  */
20621     static void
20622 f_winnr(typval_T *argvars UNUSED, typval_T *rettv)
20623 {
20624     int		nr = 1;
20625 
20626 #ifdef FEAT_WINDOWS
20627     nr = get_winnr(curtab, &argvars[0]);
20628 #endif
20629     rettv->vval.v_number = nr;
20630 }
20631 
20632 /*
20633  * "winrestcmd()" function
20634  */
20635     static void
20636 f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv)
20637 {
20638 #ifdef FEAT_WINDOWS
20639     win_T	*wp;
20640     int		winnr = 1;
20641     garray_T	ga;
20642     char_u	buf[50];
20643 
20644     ga_init2(&ga, (int)sizeof(char), 70);
20645     for (wp = firstwin; wp != NULL; wp = wp->w_next)
20646     {
20647 	sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height);
20648 	ga_concat(&ga, buf);
20649 # ifdef FEAT_VERTSPLIT
20650 	sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width);
20651 	ga_concat(&ga, buf);
20652 # endif
20653 	++winnr;
20654     }
20655     ga_append(&ga, NUL);
20656 
20657     rettv->vval.v_string = ga.ga_data;
20658 #else
20659     rettv->vval.v_string = NULL;
20660 #endif
20661     rettv->v_type = VAR_STRING;
20662 }
20663 
20664 /*
20665  * "winrestview()" function
20666  */
20667     static void
20668 f_winrestview(typval_T *argvars, typval_T *rettv UNUSED)
20669 {
20670     dict_T	*dict;
20671 
20672     if (argvars[0].v_type != VAR_DICT
20673 	    || (dict = argvars[0].vval.v_dict) == NULL)
20674 	EMSG(_(e_invarg));
20675     else
20676     {
20677 	if (dict_find(dict, (char_u *)"lnum", -1) != NULL)
20678 	    curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum");
20679 	if (dict_find(dict, (char_u *)"col", -1) != NULL)
20680 	    curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col");
20681 #ifdef FEAT_VIRTUALEDIT
20682 	if (dict_find(dict, (char_u *)"coladd", -1) != NULL)
20683 	    curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd");
20684 #endif
20685 	if (dict_find(dict, (char_u *)"curswant", -1) != NULL)
20686 	{
20687 	    curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant");
20688 	    curwin->w_set_curswant = FALSE;
20689 	}
20690 
20691 	if (dict_find(dict, (char_u *)"topline", -1) != NULL)
20692 	    set_topline(curwin, get_dict_number(dict, (char_u *)"topline"));
20693 #ifdef FEAT_DIFF
20694 	if (dict_find(dict, (char_u *)"topfill", -1) != NULL)
20695 	    curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill");
20696 #endif
20697 	if (dict_find(dict, (char_u *)"leftcol", -1) != NULL)
20698 	    curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol");
20699 	if (dict_find(dict, (char_u *)"skipcol", -1) != NULL)
20700 	    curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol");
20701 
20702 	check_cursor();
20703 	win_new_height(curwin, curwin->w_height);
20704 # ifdef FEAT_VERTSPLIT
20705 	win_new_width(curwin, W_WIDTH(curwin));
20706 # endif
20707 	changed_window_setting();
20708 
20709 	if (curwin->w_topline <= 0)
20710 	    curwin->w_topline = 1;
20711 	if (curwin->w_topline > curbuf->b_ml.ml_line_count)
20712 	    curwin->w_topline = curbuf->b_ml.ml_line_count;
20713 #ifdef FEAT_DIFF
20714 	check_topfill(curwin, TRUE);
20715 #endif
20716     }
20717 }
20718 
20719 /*
20720  * "winsaveview()" function
20721  */
20722     static void
20723 f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv)
20724 {
20725     dict_T	*dict;
20726 
20727     if (rettv_dict_alloc(rettv) == FAIL)
20728 	return;
20729     dict = rettv->vval.v_dict;
20730 
20731     dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL);
20732     dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL);
20733 #ifdef FEAT_VIRTUALEDIT
20734     dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL);
20735 #endif
20736     update_curswant();
20737     dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL);
20738 
20739     dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL);
20740 #ifdef FEAT_DIFF
20741     dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL);
20742 #endif
20743     dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL);
20744     dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL);
20745 }
20746 
20747 /*
20748  * "winwidth(nr)" function
20749  */
20750     static void
20751 f_winwidth(typval_T *argvars, typval_T *rettv)
20752 {
20753     win_T	*wp;
20754 
20755     wp = find_win_by_nr(&argvars[0], NULL);
20756     if (wp == NULL)
20757 	rettv->vval.v_number = -1;
20758     else
20759 #ifdef FEAT_VERTSPLIT
20760 	rettv->vval.v_number = wp->w_width;
20761 #else
20762 	rettv->vval.v_number = Columns;
20763 #endif
20764 }
20765 
20766 /*
20767  * "wordcount()" function
20768  */
20769     static void
20770 f_wordcount(typval_T *argvars UNUSED, typval_T *rettv)
20771 {
20772     if (rettv_dict_alloc(rettv) == FAIL)
20773 	return;
20774     cursor_pos_info(rettv->vval.v_dict);
20775 }
20776 
20777 /*
20778  * Write list of strings to file
20779  */
20780     static int
20781 write_list(FILE *fd, list_T *list, int binary)
20782 {
20783     listitem_T	*li;
20784     int		c;
20785     int		ret = OK;
20786     char_u	*s;
20787 
20788     for (li = list->lv_first; li != NULL; li = li->li_next)
20789     {
20790 	for (s = get_tv_string(&li->li_tv); *s != NUL; ++s)
20791 	{
20792 	    if (*s == '\n')
20793 		c = putc(NUL, fd);
20794 	    else
20795 		c = putc(*s, fd);
20796 	    if (c == EOF)
20797 	    {
20798 		ret = FAIL;
20799 		break;
20800 	    }
20801 	}
20802 	if (!binary || li->li_next != NULL)
20803 	    if (putc('\n', fd) == EOF)
20804 	    {
20805 		ret = FAIL;
20806 		break;
20807 	    }
20808 	if (ret == FAIL)
20809 	{
20810 	    EMSG(_(e_write));
20811 	    break;
20812 	}
20813     }
20814     return ret;
20815 }
20816 
20817 /*
20818  * "writefile()" function
20819  */
20820     static void
20821 f_writefile(typval_T *argvars, typval_T *rettv)
20822 {
20823     int		binary = FALSE;
20824     int		append = FALSE;
20825     char_u	*fname;
20826     FILE	*fd;
20827     int		ret = 0;
20828 
20829     if (check_restricted() || check_secure())
20830 	return;
20831 
20832     if (argvars[0].v_type != VAR_LIST)
20833     {
20834 	EMSG2(_(e_listarg), "writefile()");
20835 	return;
20836     }
20837     if (argvars[0].vval.v_list == NULL)
20838 	return;
20839 
20840     if (argvars[2].v_type != VAR_UNKNOWN)
20841     {
20842 	if (vim_strchr(get_tv_string(&argvars[2]), 'b') != NULL)
20843 	    binary = TRUE;
20844 	if (vim_strchr(get_tv_string(&argvars[2]), 'a') != NULL)
20845 	    append = TRUE;
20846     }
20847 
20848     /* Always open the file in binary mode, library functions have a mind of
20849      * their own about CR-LF conversion. */
20850     fname = get_tv_string(&argvars[1]);
20851     if (*fname == NUL || (fd = mch_fopen((char *)fname,
20852 				      append ? APPENDBIN : WRITEBIN)) == NULL)
20853     {
20854 	EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname);
20855 	ret = -1;
20856     }
20857     else
20858     {
20859 	if (write_list(fd, argvars[0].vval.v_list, binary) == FAIL)
20860 	    ret = -1;
20861 	fclose(fd);
20862     }
20863 
20864     rettv->vval.v_number = ret;
20865 }
20866 
20867 /*
20868  * "xor(expr, expr)" function
20869  */
20870     static void
20871 f_xor(typval_T *argvars, typval_T *rettv)
20872 {
20873     rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
20874 					^ get_tv_number_chk(&argvars[1], NULL);
20875 }
20876 
20877 
20878 /*
20879  * Translate a String variable into a position.
20880  * Returns NULL when there is an error.
20881  */
20882     static pos_T *
20883 var2fpos(
20884     typval_T	*varp,
20885     int		dollar_lnum,	/* TRUE when $ is last line */
20886     int		*fnum)		/* set to fnum for '0, 'A, etc. */
20887 {
20888     char_u		*name;
20889     static pos_T	pos;
20890     pos_T		*pp;
20891 
20892     /* Argument can be [lnum, col, coladd]. */
20893     if (varp->v_type == VAR_LIST)
20894     {
20895 	list_T		*l;
20896 	int		len;
20897 	int		error = FALSE;
20898 	listitem_T	*li;
20899 
20900 	l = varp->vval.v_list;
20901 	if (l == NULL)
20902 	    return NULL;
20903 
20904 	/* Get the line number */
20905 	pos.lnum = list_find_nr(l, 0L, &error);
20906 	if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
20907 	    return NULL;	/* invalid line number */
20908 
20909 	/* Get the column number */
20910 	pos.col = list_find_nr(l, 1L, &error);
20911 	if (error)
20912 	    return NULL;
20913 	len = (long)STRLEN(ml_get(pos.lnum));
20914 
20915 	/* We accept "$" for the column number: last column. */
20916 	li = list_find(l, 1L);
20917 	if (li != NULL && li->li_tv.v_type == VAR_STRING
20918 		&& li->li_tv.vval.v_string != NULL
20919 		&& STRCMP(li->li_tv.vval.v_string, "$") == 0)
20920 	    pos.col = len + 1;
20921 
20922 	/* Accept a position up to the NUL after the line. */
20923 	if (pos.col == 0 || (int)pos.col > len + 1)
20924 	    return NULL;	/* invalid column number */
20925 	--pos.col;
20926 
20927 #ifdef FEAT_VIRTUALEDIT
20928 	/* Get the virtual offset.  Defaults to zero. */
20929 	pos.coladd = list_find_nr(l, 2L, &error);
20930 	if (error)
20931 	    pos.coladd = 0;
20932 #endif
20933 
20934 	return &pos;
20935     }
20936 
20937     name = get_tv_string_chk(varp);
20938     if (name == NULL)
20939 	return NULL;
20940     if (name[0] == '.')				/* cursor */
20941 	return &curwin->w_cursor;
20942     if (name[0] == 'v' && name[1] == NUL)	/* Visual start */
20943     {
20944 	if (VIsual_active)
20945 	    return &VIsual;
20946 	return &curwin->w_cursor;
20947     }
20948     if (name[0] == '\'')			/* mark */
20949     {
20950 	pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum);
20951 	if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
20952 	    return NULL;
20953 	return pp;
20954     }
20955 
20956 #ifdef FEAT_VIRTUALEDIT
20957     pos.coladd = 0;
20958 #endif
20959 
20960     if (name[0] == 'w' && dollar_lnum)
20961     {
20962 	pos.col = 0;
20963 	if (name[1] == '0')		/* "w0": first visible line */
20964 	{
20965 	    update_topline();
20966 	    pos.lnum = curwin->w_topline;
20967 	    return &pos;
20968 	}
20969 	else if (name[1] == '$')	/* "w$": last visible line */
20970 	{
20971 	    validate_botline();
20972 	    pos.lnum = curwin->w_botline - 1;
20973 	    return &pos;
20974 	}
20975     }
20976     else if (name[0] == '$')		/* last column or line */
20977     {
20978 	if (dollar_lnum)
20979 	{
20980 	    pos.lnum = curbuf->b_ml.ml_line_count;
20981 	    pos.col = 0;
20982 	}
20983 	else
20984 	{
20985 	    pos.lnum = curwin->w_cursor.lnum;
20986 	    pos.col = (colnr_T)STRLEN(ml_get_curline());
20987 	}
20988 	return &pos;
20989     }
20990     return NULL;
20991 }
20992 
20993 /*
20994  * Convert list in "arg" into a position and optional file number.
20995  * When "fnump" is NULL there is no file number, only 3 items.
20996  * Note that the column is passed on as-is, the caller may want to decrement
20997  * it to use 1 for the first column.
20998  * Return FAIL when conversion is not possible, doesn't check the position for
20999  * validity.
21000  */
21001     static int
21002 list2fpos(
21003     typval_T	*arg,
21004     pos_T	*posp,
21005     int		*fnump,
21006     colnr_T	*curswantp)
21007 {
21008     list_T	*l = arg->vval.v_list;
21009     long	i = 0;
21010     long	n;
21011 
21012     /* List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only
21013      * there when "fnump" isn't NULL; "coladd" and "curswant" are optional. */
21014     if (arg->v_type != VAR_LIST
21015 	    || l == NULL
21016 	    || l->lv_len < (fnump == NULL ? 2 : 3)
21017 	    || l->lv_len > (fnump == NULL ? 4 : 5))
21018 	return FAIL;
21019 
21020     if (fnump != NULL)
21021     {
21022 	n = list_find_nr(l, i++, NULL);	/* fnum */
21023 	if (n < 0)
21024 	    return FAIL;
21025 	if (n == 0)
21026 	    n = curbuf->b_fnum;		/* current buffer */
21027 	*fnump = n;
21028     }
21029 
21030     n = list_find_nr(l, i++, NULL);	/* lnum */
21031     if (n < 0)
21032 	return FAIL;
21033     posp->lnum = n;
21034 
21035     n = list_find_nr(l, i++, NULL);	/* col */
21036     if (n < 0)
21037 	return FAIL;
21038     posp->col = n;
21039 
21040 #ifdef FEAT_VIRTUALEDIT
21041     n = list_find_nr(l, i, NULL);	/* off */
21042     if (n < 0)
21043 	posp->coladd = 0;
21044     else
21045 	posp->coladd = n;
21046 #endif
21047 
21048     if (curswantp != NULL)
21049 	*curswantp = list_find_nr(l, i + 1, NULL);  /* curswant */
21050 
21051     return OK;
21052 }
21053 
21054 /*
21055  * Get the length of an environment variable name.
21056  * Advance "arg" to the first character after the name.
21057  * Return 0 for error.
21058  */
21059     static int
21060 get_env_len(char_u **arg)
21061 {
21062     char_u	*p;
21063     int		len;
21064 
21065     for (p = *arg; vim_isIDc(*p); ++p)
21066 	;
21067     if (p == *arg)	    /* no name found */
21068 	return 0;
21069 
21070     len = (int)(p - *arg);
21071     *arg = p;
21072     return len;
21073 }
21074 
21075 /*
21076  * Get the length of the name of a function or internal variable.
21077  * "arg" is advanced to the first non-white character after the name.
21078  * Return 0 if something is wrong.
21079  */
21080     static int
21081 get_id_len(char_u **arg)
21082 {
21083     char_u	*p;
21084     int		len;
21085 
21086     /* Find the end of the name. */
21087     for (p = *arg; eval_isnamec(*p); ++p)
21088     {
21089 	if (*p == ':')
21090 	{
21091 	    /* "s:" is start of "s:var", but "n:" is not and can be used in
21092 	     * slice "[n:]".  Also "xx:" is not a namespace. */
21093 	    len = (int)(p - *arg);
21094 	    if ((len == 1 && vim_strchr(NAMESPACE_CHAR, **arg) == NULL)
21095 		    || len > 1)
21096 		break;
21097 	}
21098     }
21099     if (p == *arg)	    /* no name found */
21100 	return 0;
21101 
21102     len = (int)(p - *arg);
21103     *arg = skipwhite(p);
21104 
21105     return len;
21106 }
21107 
21108 /*
21109  * Get the length of the name of a variable or function.
21110  * Only the name is recognized, does not handle ".key" or "[idx]".
21111  * "arg" is advanced to the first non-white character after the name.
21112  * Return -1 if curly braces expansion failed.
21113  * Return 0 if something else is wrong.
21114  * If the name contains 'magic' {}'s, expand them and return the
21115  * expanded name in an allocated string via 'alias' - caller must free.
21116  */
21117     static int
21118 get_name_len(
21119     char_u	**arg,
21120     char_u	**alias,
21121     int		evaluate,
21122     int		verbose)
21123 {
21124     int		len;
21125     char_u	*p;
21126     char_u	*expr_start;
21127     char_u	*expr_end;
21128 
21129     *alias = NULL;  /* default to no alias */
21130 
21131     if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
21132 						  && (*arg)[2] == (int)KE_SNR)
21133     {
21134 	/* hard coded <SNR>, already translated */
21135 	*arg += 3;
21136 	return get_id_len(arg) + 3;
21137     }
21138     len = eval_fname_script(*arg);
21139     if (len > 0)
21140     {
21141 	/* literal "<SID>", "s:" or "<SNR>" */
21142 	*arg += len;
21143     }
21144 
21145     /*
21146      * Find the end of the name; check for {} construction.
21147      */
21148     p = find_name_end(*arg, &expr_start, &expr_end,
21149 					       len > 0 ? 0 : FNE_CHECK_START);
21150     if (expr_start != NULL)
21151     {
21152 	char_u	*temp_string;
21153 
21154 	if (!evaluate)
21155 	{
21156 	    len += (int)(p - *arg);
21157 	    *arg = skipwhite(p);
21158 	    return len;
21159 	}
21160 
21161 	/*
21162 	 * Include any <SID> etc in the expanded string:
21163 	 * Thus the -len here.
21164 	 */
21165 	temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
21166 	if (temp_string == NULL)
21167 	    return -1;
21168 	*alias = temp_string;
21169 	*arg = skipwhite(p);
21170 	return (int)STRLEN(temp_string);
21171     }
21172 
21173     len += get_id_len(arg);
21174     if (len == 0 && verbose)
21175 	EMSG2(_(e_invexpr2), *arg);
21176 
21177     return len;
21178 }
21179 
21180 /*
21181  * Find the end of a variable or function name, taking care of magic braces.
21182  * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the
21183  * start and end of the first magic braces item.
21184  * "flags" can have FNE_INCL_BR and FNE_CHECK_START.
21185  * Return a pointer to just after the name.  Equal to "arg" if there is no
21186  * valid name.
21187  */
21188     static char_u *
21189 find_name_end(
21190     char_u	*arg,
21191     char_u	**expr_start,
21192     char_u	**expr_end,
21193     int		flags)
21194 {
21195     int		mb_nest = 0;
21196     int		br_nest = 0;
21197     char_u	*p;
21198     int		len;
21199 
21200     if (expr_start != NULL)
21201     {
21202 	*expr_start = NULL;
21203 	*expr_end = NULL;
21204     }
21205 
21206     /* Quick check for valid starting character. */
21207     if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{')
21208 	return arg;
21209 
21210     for (p = arg; *p != NUL
21211 		    && (eval_isnamec(*p)
21212 			|| *p == '{'
21213 			|| ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.'))
21214 			|| mb_nest != 0
21215 			|| br_nest != 0); mb_ptr_adv(p))
21216     {
21217 	if (*p == '\'')
21218 	{
21219 	    /* skip over 'string' to avoid counting [ and ] inside it. */
21220 	    for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p))
21221 		;
21222 	    if (*p == NUL)
21223 		break;
21224 	}
21225 	else if (*p == '"')
21226 	{
21227 	    /* skip over "str\"ing" to avoid counting [ and ] inside it. */
21228 	    for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p))
21229 		if (*p == '\\' && p[1] != NUL)
21230 		    ++p;
21231 	    if (*p == NUL)
21232 		break;
21233 	}
21234 	else if (br_nest == 0 && mb_nest == 0 && *p == ':')
21235 	{
21236 	    /* "s:" is start of "s:var", but "n:" is not and can be used in
21237 	     * slice "[n:]".  Also "xx:" is not a namespace. But {ns}: is. */
21238 	    len = (int)(p - arg);
21239 	    if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL)
21240 		    || (len > 1 && p[-1] != '}'))
21241 		break;
21242 	}
21243 
21244 	if (mb_nest == 0)
21245 	{
21246 	    if (*p == '[')
21247 		++br_nest;
21248 	    else if (*p == ']')
21249 		--br_nest;
21250 	}
21251 
21252 	if (br_nest == 0)
21253 	{
21254 	    if (*p == '{')
21255 	    {
21256 		mb_nest++;
21257 		if (expr_start != NULL && *expr_start == NULL)
21258 		    *expr_start = p;
21259 	    }
21260 	    else if (*p == '}')
21261 	    {
21262 		mb_nest--;
21263 		if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL)
21264 		    *expr_end = p;
21265 	    }
21266 	}
21267     }
21268 
21269     return p;
21270 }
21271 
21272 /*
21273  * Expands out the 'magic' {}'s in a variable/function name.
21274  * Note that this can call itself recursively, to deal with
21275  * constructs like foo{bar}{baz}{bam}
21276  * The four pointer arguments point to "foo{expre}ss{ion}bar"
21277  *			"in_start"      ^
21278  *			"expr_start"	   ^
21279  *			"expr_end"		 ^
21280  *			"in_end"			    ^
21281  *
21282  * Returns a new allocated string, which the caller must free.
21283  * Returns NULL for failure.
21284  */
21285     static char_u *
21286 make_expanded_name(
21287     char_u	*in_start,
21288     char_u	*expr_start,
21289     char_u	*expr_end,
21290     char_u	*in_end)
21291 {
21292     char_u	c1;
21293     char_u	*retval = NULL;
21294     char_u	*temp_result;
21295     char_u	*nextcmd = NULL;
21296 
21297     if (expr_end == NULL || in_end == NULL)
21298 	return NULL;
21299     *expr_start	= NUL;
21300     *expr_end = NUL;
21301     c1 = *in_end;
21302     *in_end = NUL;
21303 
21304     temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE);
21305     if (temp_result != NULL && nextcmd == NULL)
21306     {
21307 	retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start)
21308 						   + (in_end - expr_end) + 1));
21309 	if (retval != NULL)
21310 	{
21311 	    STRCPY(retval, in_start);
21312 	    STRCAT(retval, temp_result);
21313 	    STRCAT(retval, expr_end + 1);
21314 	}
21315     }
21316     vim_free(temp_result);
21317 
21318     *in_end = c1;		/* put char back for error messages */
21319     *expr_start = '{';
21320     *expr_end = '}';
21321 
21322     if (retval != NULL)
21323     {
21324 	temp_result = find_name_end(retval, &expr_start, &expr_end, 0);
21325 	if (expr_start != NULL)
21326 	{
21327 	    /* Further expansion! */
21328 	    temp_result = make_expanded_name(retval, expr_start,
21329 						       expr_end, temp_result);
21330 	    vim_free(retval);
21331 	    retval = temp_result;
21332 	}
21333     }
21334 
21335     return retval;
21336 }
21337 
21338 /*
21339  * Return TRUE if character "c" can be used in a variable or function name.
21340  * Does not include '{' or '}' for magic braces.
21341  */
21342     static int
21343 eval_isnamec(int c)
21344 {
21345     return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR);
21346 }
21347 
21348 /*
21349  * Return TRUE if character "c" can be used as the first character in a
21350  * variable or function name (excluding '{' and '}').
21351  */
21352     static int
21353 eval_isnamec1(int c)
21354 {
21355     return (ASCII_ISALPHA(c) || c == '_');
21356 }
21357 
21358 /*
21359  * Set number v: variable to "val".
21360  */
21361     void
21362 set_vim_var_nr(int idx, long val)
21363 {
21364     vimvars[idx].vv_nr = val;
21365 }
21366 
21367 /*
21368  * Get number v: variable value.
21369  */
21370     long
21371 get_vim_var_nr(int idx)
21372 {
21373     return vimvars[idx].vv_nr;
21374 }
21375 
21376 /*
21377  * Get string v: variable value.  Uses a static buffer, can only be used once.
21378  */
21379     char_u *
21380 get_vim_var_str(int idx)
21381 {
21382     return get_tv_string(&vimvars[idx].vv_tv);
21383 }
21384 
21385 /*
21386  * Get List v: variable value.  Caller must take care of reference count when
21387  * needed.
21388  */
21389     list_T *
21390 get_vim_var_list(int idx)
21391 {
21392     return vimvars[idx].vv_list;
21393 }
21394 
21395 /*
21396  * Set v:char to character "c".
21397  */
21398     void
21399 set_vim_var_char(int c)
21400 {
21401     char_u	buf[MB_MAXBYTES + 1];
21402 
21403 #ifdef FEAT_MBYTE
21404     if (has_mbyte)
21405 	buf[(*mb_char2bytes)(c, buf)] = NUL;
21406     else
21407 #endif
21408     {
21409 	buf[0] = c;
21410 	buf[1] = NUL;
21411     }
21412     set_vim_var_string(VV_CHAR, buf, -1);
21413 }
21414 
21415 /*
21416  * Set v:count to "count" and v:count1 to "count1".
21417  * When "set_prevcount" is TRUE first set v:prevcount from v:count.
21418  */
21419     void
21420 set_vcount(
21421     long	count,
21422     long	count1,
21423     int		set_prevcount)
21424 {
21425     if (set_prevcount)
21426 	vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
21427     vimvars[VV_COUNT].vv_nr = count;
21428     vimvars[VV_COUNT1].vv_nr = count1;
21429 }
21430 
21431 /*
21432  * Set string v: variable to a copy of "val".
21433  */
21434     void
21435 set_vim_var_string(
21436     int		idx,
21437     char_u	*val,
21438     int		len)	    /* length of "val" to use or -1 (whole string) */
21439 {
21440     clear_tv(&vimvars[idx].vv_di.di_tv);
21441     vimvars[idx].vv_type = VAR_STRING;
21442     if (val == NULL)
21443 	vimvars[idx].vv_str = NULL;
21444     else if (len == -1)
21445 	vimvars[idx].vv_str = vim_strsave(val);
21446     else
21447 	vimvars[idx].vv_str = vim_strnsave(val, len);
21448 }
21449 
21450 /*
21451  * Set List v: variable to "val".
21452  */
21453     void
21454 set_vim_var_list(int idx, list_T *val)
21455 {
21456     clear_tv(&vimvars[idx].vv_di.di_tv);
21457     vimvars[idx].vv_type = VAR_LIST;
21458     vimvars[idx].vv_list = val;
21459     if (val != NULL)
21460 	++val->lv_refcount;
21461 }
21462 
21463 /*
21464  * Set Dictionary v: variable to "val".
21465  */
21466     void
21467 set_vim_var_dict(int idx, dict_T *val)
21468 {
21469     int		todo;
21470     hashitem_T	*hi;
21471 
21472     clear_tv(&vimvars[idx].vv_di.di_tv);
21473     vimvars[idx].vv_type = VAR_DICT;
21474     vimvars[idx].vv_dict = val;
21475     if (val != NULL)
21476     {
21477 	++val->dv_refcount;
21478 
21479 	/* Set readonly */
21480 	todo = (int)val->dv_hashtab.ht_used;
21481 	for (hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi)
21482 	{
21483 	    if (HASHITEM_EMPTY(hi))
21484 		continue;
21485 	    --todo;
21486 	    HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
21487 	}
21488     }
21489 }
21490 
21491 /*
21492  * Set v:register if needed.
21493  */
21494     void
21495 set_reg_var(int c)
21496 {
21497     char_u	regname;
21498 
21499     if (c == 0 || c == ' ')
21500 	regname = '"';
21501     else
21502 	regname = c;
21503     /* Avoid free/alloc when the value is already right. */
21504     if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c)
21505 	set_vim_var_string(VV_REG, &regname, 1);
21506 }
21507 
21508 /*
21509  * Get or set v:exception.  If "oldval" == NULL, return the current value.
21510  * Otherwise, restore the value to "oldval" and return NULL.
21511  * Must always be called in pairs to save and restore v:exception!  Does not
21512  * take care of memory allocations.
21513  */
21514     char_u *
21515 v_exception(char_u *oldval)
21516 {
21517     if (oldval == NULL)
21518 	return vimvars[VV_EXCEPTION].vv_str;
21519 
21520     vimvars[VV_EXCEPTION].vv_str = oldval;
21521     return NULL;
21522 }
21523 
21524 /*
21525  * Get or set v:throwpoint.  If "oldval" == NULL, return the current value.
21526  * Otherwise, restore the value to "oldval" and return NULL.
21527  * Must always be called in pairs to save and restore v:throwpoint!  Does not
21528  * take care of memory allocations.
21529  */
21530     char_u *
21531 v_throwpoint(char_u *oldval)
21532 {
21533     if (oldval == NULL)
21534 	return vimvars[VV_THROWPOINT].vv_str;
21535 
21536     vimvars[VV_THROWPOINT].vv_str = oldval;
21537     return NULL;
21538 }
21539 
21540 #if defined(FEAT_AUTOCMD) || defined(PROTO)
21541 /*
21542  * Set v:cmdarg.
21543  * If "eap" != NULL, use "eap" to generate the value and return the old value.
21544  * If "oldarg" != NULL, restore the value to "oldarg" and return NULL.
21545  * Must always be called in pairs!
21546  */
21547     char_u *
21548 set_cmdarg(exarg_T *eap, char_u *oldarg)
21549 {
21550     char_u	*oldval;
21551     char_u	*newval;
21552     unsigned	len;
21553 
21554     oldval = vimvars[VV_CMDARG].vv_str;
21555     if (eap == NULL)
21556     {
21557 	vim_free(oldval);
21558 	vimvars[VV_CMDARG].vv_str = oldarg;
21559 	return NULL;
21560     }
21561 
21562     if (eap->force_bin == FORCE_BIN)
21563 	len = 6;
21564     else if (eap->force_bin == FORCE_NOBIN)
21565 	len = 8;
21566     else
21567 	len = 0;
21568 
21569     if (eap->read_edit)
21570 	len += 7;
21571 
21572     if (eap->force_ff != 0)
21573 	len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
21574 # ifdef FEAT_MBYTE
21575     if (eap->force_enc != 0)
21576 	len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
21577     if (eap->bad_char != 0)
21578 	len += 7 + 4;  /* " ++bad=" + "keep" or "drop" */
21579 # endif
21580 
21581     newval = alloc(len + 1);
21582     if (newval == NULL)
21583 	return NULL;
21584 
21585     if (eap->force_bin == FORCE_BIN)
21586 	sprintf((char *)newval, " ++bin");
21587     else if (eap->force_bin == FORCE_NOBIN)
21588 	sprintf((char *)newval, " ++nobin");
21589     else
21590 	*newval = NUL;
21591 
21592     if (eap->read_edit)
21593 	STRCAT(newval, " ++edit");
21594 
21595     if (eap->force_ff != 0)
21596 	sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
21597 						eap->cmd + eap->force_ff);
21598 # ifdef FEAT_MBYTE
21599     if (eap->force_enc != 0)
21600 	sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
21601 					       eap->cmd + eap->force_enc);
21602     if (eap->bad_char == BAD_KEEP)
21603 	STRCPY(newval + STRLEN(newval), " ++bad=keep");
21604     else if (eap->bad_char == BAD_DROP)
21605 	STRCPY(newval + STRLEN(newval), " ++bad=drop");
21606     else if (eap->bad_char != 0)
21607 	sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char);
21608 # endif
21609     vimvars[VV_CMDARG].vv_str = newval;
21610     return oldval;
21611 }
21612 #endif
21613 
21614 /*
21615  * Get the value of internal variable "name".
21616  * Return OK or FAIL.
21617  */
21618     static int
21619 get_var_tv(
21620     char_u	*name,
21621     int		len,		/* length of "name" */
21622     typval_T	*rettv,		/* NULL when only checking existence */
21623     dictitem_T	**dip,		/* non-NULL when typval's dict item is needed */
21624     int		verbose,	/* may give error message */
21625     int		no_autoload)	/* do not use script autoloading */
21626 {
21627     int		ret = OK;
21628     typval_T	*tv = NULL;
21629     typval_T	atv;
21630     dictitem_T	*v;
21631     int		cc;
21632 
21633     /* truncate the name, so that we can use strcmp() */
21634     cc = name[len];
21635     name[len] = NUL;
21636 
21637     /*
21638      * Check for "b:changedtick".
21639      */
21640     if (STRCMP(name, "b:changedtick") == 0)
21641     {
21642 	atv.v_type = VAR_NUMBER;
21643 	atv.vval.v_number = curbuf->b_changedtick;
21644 	tv = &atv;
21645     }
21646 
21647     /*
21648      * Check for user-defined variables.
21649      */
21650     else
21651     {
21652 	v = find_var(name, NULL, no_autoload);
21653 	if (v != NULL)
21654 	{
21655 	    tv = &v->di_tv;
21656 	    if (dip != NULL)
21657 		*dip = v;
21658 	}
21659     }
21660 
21661     if (tv == NULL)
21662     {
21663 	if (rettv != NULL && verbose)
21664 	    EMSG2(_(e_undefvar), name);
21665 	ret = FAIL;
21666     }
21667     else if (rettv != NULL)
21668 	copy_tv(tv, rettv);
21669 
21670     name[len] = cc;
21671 
21672     return ret;
21673 }
21674 
21675 /*
21676  * Handle expr[expr], expr[expr:expr] subscript and .name lookup.
21677  * Also handle function call with Funcref variable: func(expr)
21678  * Can all be combined: dict.func(expr)[idx]['func'](expr)
21679  */
21680     static int
21681 handle_subscript(
21682     char_u	**arg,
21683     typval_T	*rettv,
21684     int		evaluate,	/* do more than finding the end */
21685     int		verbose)	/* give error messages */
21686 {
21687     int		ret = OK;
21688     dict_T	*selfdict = NULL;
21689     char_u	*s;
21690     int		len;
21691     typval_T	functv;
21692 
21693     while (ret == OK
21694 	    && (**arg == '['
21695 		|| (**arg == '.' && rettv->v_type == VAR_DICT)
21696 		|| (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
21697 					    || rettv->v_type == VAR_PARTIAL)))
21698 	    && !vim_iswhite(*(*arg - 1)))
21699     {
21700 	if (**arg == '(')
21701 	{
21702 	    partial_T	*pt = NULL;
21703 
21704 	    /* need to copy the funcref so that we can clear rettv */
21705 	    if (evaluate)
21706 	    {
21707 		functv = *rettv;
21708 		rettv->v_type = VAR_UNKNOWN;
21709 
21710 		/* Invoke the function.  Recursive! */
21711 		if (functv.v_type == VAR_PARTIAL)
21712 		{
21713 		    pt = functv.vval.v_partial;
21714 		    s = pt->pt_name;
21715 		}
21716 		else
21717 		    s = functv.vval.v_string;
21718 	    }
21719 	    else
21720 		s = (char_u *)"";
21721 	    ret = get_func_tv(s, (int)STRLEN(s), rettv, arg,
21722 			curwin->w_cursor.lnum, curwin->w_cursor.lnum,
21723 			&len, evaluate, pt, selfdict);
21724 
21725 	    /* Clear the funcref afterwards, so that deleting it while
21726 	     * evaluating the arguments is possible (see test55). */
21727 	    if (evaluate)
21728 		clear_tv(&functv);
21729 
21730 	    /* Stop the expression evaluation when immediately aborting on
21731 	     * error, or when an interrupt occurred or an exception was thrown
21732 	     * but not caught. */
21733 	    if (aborting())
21734 	    {
21735 		if (ret == OK)
21736 		    clear_tv(rettv);
21737 		ret = FAIL;
21738 	    }
21739 	    dict_unref(selfdict);
21740 	    selfdict = NULL;
21741 	}
21742 	else /* **arg == '[' || **arg == '.' */
21743 	{
21744 	    dict_unref(selfdict);
21745 	    if (rettv->v_type == VAR_DICT)
21746 	    {
21747 		selfdict = rettv->vval.v_dict;
21748 		if (selfdict != NULL)
21749 		    ++selfdict->dv_refcount;
21750 	    }
21751 	    else
21752 		selfdict = NULL;
21753 	    if (eval_index(arg, rettv, evaluate, verbose) == FAIL)
21754 	    {
21755 		clear_tv(rettv);
21756 		ret = FAIL;
21757 	    }
21758 	}
21759     }
21760 
21761     if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL)
21762 							  && selfdict != NULL)
21763     {
21764 	char_u	    *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
21765 					     : rettv->vval.v_partial->pt_name;
21766 	char_u	    *tofree = NULL;
21767 	ufunc_T	    *fp;
21768 	char_u	    fname_buf[FLEN_FIXED + 1];
21769 	int	    error;
21770 
21771 	/* Translate "s:func" to the stored function name. */
21772 	fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
21773 	fp = find_func(fname);
21774 	vim_free(tofree);
21775 
21776 	/* Turn "dict.Func" into a partial for "Func" with "dict". */
21777 	if (fp != NULL && (fp->uf_flags & FC_DICT))
21778 	{
21779 	    partial_T	*pt = (partial_T *)alloc_clear(sizeof(partial_T));
21780 
21781 	    if (pt != NULL)
21782 	    {
21783 		pt->pt_refcount = 1;
21784 		pt->pt_dict = selfdict;
21785 		selfdict = NULL;
21786 		if (rettv->v_type == VAR_FUNC)
21787 		{
21788 		    /* just a function: use selfdict */
21789 		    pt->pt_name = rettv->vval.v_string;
21790 		}
21791 		else
21792 		{
21793 		    partial_T	*ret_pt = rettv->vval.v_partial;
21794 		    int		i;
21795 
21796 		    /* partial: use selfdict and copy args */
21797 		    pt->pt_name = vim_strsave(ret_pt->pt_name);
21798 		    if (ret_pt->pt_argc > 0)
21799 		    {
21800 			pt->pt_argv = (typval_T *)alloc(
21801 					  sizeof(typval_T) * ret_pt->pt_argc);
21802 			if (pt->pt_argv == NULL)
21803 			    /* out of memory: drop the arguments */
21804 			    pt->pt_argc = 0;
21805 			else
21806 			{
21807 			    pt->pt_argc = ret_pt->pt_argc;
21808 			    for (i = 0; i < pt->pt_argc; i++)
21809 				copy_tv(&ret_pt->pt_argv[i], &pt->pt_argv[i]);
21810 			}
21811 		    }
21812 		    partial_unref(ret_pt);
21813 		}
21814 		func_ref(pt->pt_name);
21815 		rettv->v_type = VAR_PARTIAL;
21816 		rettv->vval.v_partial = pt;
21817 	    }
21818 	}
21819     }
21820 
21821     dict_unref(selfdict);
21822     return ret;
21823 }
21824 
21825 /*
21826  * Allocate memory for a variable type-value, and make it empty (0 or NULL
21827  * value).
21828  */
21829     typval_T *
21830 alloc_tv(void)
21831 {
21832     return (typval_T *)alloc_clear((unsigned)sizeof(typval_T));
21833 }
21834 
21835 /*
21836  * Allocate memory for a variable type-value, and assign a string to it.
21837  * The string "s" must have been allocated, it is consumed.
21838  * Return NULL for out of memory, the variable otherwise.
21839  */
21840     static typval_T *
21841 alloc_string_tv(char_u *s)
21842 {
21843     typval_T	*rettv;
21844 
21845     rettv = alloc_tv();
21846     if (rettv != NULL)
21847     {
21848 	rettv->v_type = VAR_STRING;
21849 	rettv->vval.v_string = s;
21850     }
21851     else
21852 	vim_free(s);
21853     return rettv;
21854 }
21855 
21856 /*
21857  * Free the memory for a variable type-value.
21858  */
21859     void
21860 free_tv(typval_T *varp)
21861 {
21862     if (varp != NULL)
21863     {
21864 	switch (varp->v_type)
21865 	{
21866 	    case VAR_FUNC:
21867 		func_unref(varp->vval.v_string);
21868 		/*FALLTHROUGH*/
21869 	    case VAR_STRING:
21870 		vim_free(varp->vval.v_string);
21871 		break;
21872 	    case VAR_PARTIAL:
21873 		partial_unref(varp->vval.v_partial);
21874 		break;
21875 	    case VAR_LIST:
21876 		list_unref(varp->vval.v_list);
21877 		break;
21878 	    case VAR_DICT:
21879 		dict_unref(varp->vval.v_dict);
21880 		break;
21881 	    case VAR_JOB:
21882 #ifdef FEAT_JOB_CHANNEL
21883 		job_unref(varp->vval.v_job);
21884 		break;
21885 #endif
21886 	    case VAR_CHANNEL:
21887 #ifdef FEAT_JOB_CHANNEL
21888 		channel_unref(varp->vval.v_channel);
21889 		break;
21890 #endif
21891 	    case VAR_NUMBER:
21892 	    case VAR_FLOAT:
21893 	    case VAR_UNKNOWN:
21894 	    case VAR_SPECIAL:
21895 		break;
21896 	}
21897 	vim_free(varp);
21898     }
21899 }
21900 
21901 /*
21902  * Free the memory for a variable value and set the value to NULL or 0.
21903  */
21904     void
21905 clear_tv(typval_T *varp)
21906 {
21907     if (varp != NULL)
21908     {
21909 	switch (varp->v_type)
21910 	{
21911 	    case VAR_FUNC:
21912 		func_unref(varp->vval.v_string);
21913 		/*FALLTHROUGH*/
21914 	    case VAR_STRING:
21915 		vim_free(varp->vval.v_string);
21916 		varp->vval.v_string = NULL;
21917 		break;
21918 	    case VAR_PARTIAL:
21919 		partial_unref(varp->vval.v_partial);
21920 		varp->vval.v_partial = NULL;
21921 		break;
21922 	    case VAR_LIST:
21923 		list_unref(varp->vval.v_list);
21924 		varp->vval.v_list = NULL;
21925 		break;
21926 	    case VAR_DICT:
21927 		dict_unref(varp->vval.v_dict);
21928 		varp->vval.v_dict = NULL;
21929 		break;
21930 	    case VAR_NUMBER:
21931 	    case VAR_SPECIAL:
21932 		varp->vval.v_number = 0;
21933 		break;
21934 	    case VAR_FLOAT:
21935 #ifdef FEAT_FLOAT
21936 		varp->vval.v_float = 0.0;
21937 		break;
21938 #endif
21939 	    case VAR_JOB:
21940 #ifdef FEAT_JOB_CHANNEL
21941 		job_unref(varp->vval.v_job);
21942 		varp->vval.v_job = NULL;
21943 #endif
21944 		break;
21945 	    case VAR_CHANNEL:
21946 #ifdef FEAT_JOB_CHANNEL
21947 		channel_unref(varp->vval.v_channel);
21948 		varp->vval.v_channel = NULL;
21949 #endif
21950 	    case VAR_UNKNOWN:
21951 		break;
21952 	}
21953 	varp->v_lock = 0;
21954     }
21955 }
21956 
21957 /*
21958  * Set the value of a variable to NULL without freeing items.
21959  */
21960     static void
21961 init_tv(typval_T *varp)
21962 {
21963     if (varp != NULL)
21964 	vim_memset(varp, 0, sizeof(typval_T));
21965 }
21966 
21967 /*
21968  * Get the number value of a variable.
21969  * If it is a String variable, uses vim_str2nr().
21970  * For incompatible types, return 0.
21971  * get_tv_number_chk() is similar to get_tv_number(), but informs the
21972  * caller of incompatible types: it sets *denote to TRUE if "denote"
21973  * is not NULL or returns -1 otherwise.
21974  */
21975     long
21976 get_tv_number(typval_T *varp)
21977 {
21978     int		error = FALSE;
21979 
21980     return get_tv_number_chk(varp, &error);	/* return 0L on error */
21981 }
21982 
21983     long
21984 get_tv_number_chk(typval_T *varp, int *denote)
21985 {
21986     long	n = 0L;
21987 
21988     switch (varp->v_type)
21989     {
21990 	case VAR_NUMBER:
21991 	    return (long)(varp->vval.v_number);
21992 	case VAR_FLOAT:
21993 #ifdef FEAT_FLOAT
21994 	    EMSG(_("E805: Using a Float as a Number"));
21995 	    break;
21996 #endif
21997 	case VAR_FUNC:
21998 	case VAR_PARTIAL:
21999 	    EMSG(_("E703: Using a Funcref as a Number"));
22000 	    break;
22001 	case VAR_STRING:
22002 	    if (varp->vval.v_string != NULL)
22003 		vim_str2nr(varp->vval.v_string, NULL, NULL,
22004 						    STR2NR_ALL, &n, NULL, 0);
22005 	    return n;
22006 	case VAR_LIST:
22007 	    EMSG(_("E745: Using a List as a Number"));
22008 	    break;
22009 	case VAR_DICT:
22010 	    EMSG(_("E728: Using a Dictionary as a Number"));
22011 	    break;
22012 	case VAR_SPECIAL:
22013 	    return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
22014 	    break;
22015 	case VAR_JOB:
22016 #ifdef FEAT_JOB_CHANNEL
22017 	    EMSG(_("E910: Using a Job as a Number"));
22018 	    break;
22019 #endif
22020 	case VAR_CHANNEL:
22021 #ifdef FEAT_JOB_CHANNEL
22022 	    EMSG(_("E913: Using a Channel as a Number"));
22023 	    break;
22024 #endif
22025 	case VAR_UNKNOWN:
22026 	    EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)");
22027 	    break;
22028     }
22029     if (denote == NULL)		/* useful for values that must be unsigned */
22030 	n = -1;
22031     else
22032 	*denote = TRUE;
22033     return n;
22034 }
22035 
22036 #ifdef FEAT_FLOAT
22037     static float_T
22038 get_tv_float(typval_T *varp)
22039 {
22040     switch (varp->v_type)
22041     {
22042 	case VAR_NUMBER:
22043 	    return (float_T)(varp->vval.v_number);
22044 	case VAR_FLOAT:
22045 	    return varp->vval.v_float;
22046 	case VAR_FUNC:
22047 	case VAR_PARTIAL:
22048 	    EMSG(_("E891: Using a Funcref as a Float"));
22049 	    break;
22050 	case VAR_STRING:
22051 	    EMSG(_("E892: Using a String as a Float"));
22052 	    break;
22053 	case VAR_LIST:
22054 	    EMSG(_("E893: Using a List as a Float"));
22055 	    break;
22056 	case VAR_DICT:
22057 	    EMSG(_("E894: Using a Dictionary as a Float"));
22058 	    break;
22059 	case VAR_SPECIAL:
22060 	    EMSG(_("E907: Using a special value as a Float"));
22061 	    break;
22062 	case VAR_JOB:
22063 # ifdef FEAT_JOB_CHANNEL
22064 	    EMSG(_("E911: Using a Job as a Float"));
22065 	    break;
22066 # endif
22067 	case VAR_CHANNEL:
22068 # ifdef FEAT_JOB_CHANNEL
22069 	    EMSG(_("E914: Using a Channel as a Float"));
22070 	    break;
22071 # endif
22072 	case VAR_UNKNOWN:
22073 	    EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)");
22074 	    break;
22075     }
22076     return 0;
22077 }
22078 #endif
22079 
22080 /*
22081  * Get the lnum from the first argument.
22082  * Also accepts ".", "$", etc., but that only works for the current buffer.
22083  * Returns -1 on error.
22084  */
22085     static linenr_T
22086 get_tv_lnum(typval_T *argvars)
22087 {
22088     typval_T	rettv;
22089     linenr_T	lnum;
22090 
22091     lnum = get_tv_number_chk(&argvars[0], NULL);
22092     if (lnum == 0)  /* no valid number, try using line() */
22093     {
22094 	rettv.v_type = VAR_NUMBER;
22095 	f_line(argvars, &rettv);
22096 	lnum = rettv.vval.v_number;
22097 	clear_tv(&rettv);
22098     }
22099     return lnum;
22100 }
22101 
22102 /*
22103  * Get the lnum from the first argument.
22104  * Also accepts "$", then "buf" is used.
22105  * Returns 0 on error.
22106  */
22107     static linenr_T
22108 get_tv_lnum_buf(typval_T *argvars, buf_T *buf)
22109 {
22110     if (argvars[0].v_type == VAR_STRING
22111 	    && argvars[0].vval.v_string != NULL
22112 	    && argvars[0].vval.v_string[0] == '$'
22113 	    && buf != NULL)
22114 	return buf->b_ml.ml_line_count;
22115     return get_tv_number_chk(&argvars[0], NULL);
22116 }
22117 
22118 /*
22119  * Get the string value of a variable.
22120  * If it is a Number variable, the number is converted into a string.
22121  * get_tv_string() uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
22122  * get_tv_string_buf() uses a given buffer.
22123  * If the String variable has never been set, return an empty string.
22124  * Never returns NULL;
22125  * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return
22126  * NULL on error.
22127  */
22128     char_u *
22129 get_tv_string(typval_T *varp)
22130 {
22131     static char_u   mybuf[NUMBUFLEN];
22132 
22133     return get_tv_string_buf(varp, mybuf);
22134 }
22135 
22136     char_u *
22137 get_tv_string_buf(typval_T *varp, char_u *buf)
22138 {
22139     char_u	*res =  get_tv_string_buf_chk(varp, buf);
22140 
22141     return res != NULL ? res : (char_u *)"";
22142 }
22143 
22144 /*
22145  * Careful: This uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
22146  */
22147     char_u *
22148 get_tv_string_chk(typval_T *varp)
22149 {
22150     static char_u   mybuf[NUMBUFLEN];
22151 
22152     return get_tv_string_buf_chk(varp, mybuf);
22153 }
22154 
22155     char_u *
22156 get_tv_string_buf_chk(typval_T *varp, char_u *buf)
22157 {
22158     switch (varp->v_type)
22159     {
22160 	case VAR_NUMBER:
22161 	    sprintf((char *)buf, "%ld", (long)varp->vval.v_number);
22162 	    return buf;
22163 	case VAR_FUNC:
22164 	case VAR_PARTIAL:
22165 	    EMSG(_("E729: using Funcref as a String"));
22166 	    break;
22167 	case VAR_LIST:
22168 	    EMSG(_("E730: using List as a String"));
22169 	    break;
22170 	case VAR_DICT:
22171 	    EMSG(_("E731: using Dictionary as a String"));
22172 	    break;
22173 	case VAR_FLOAT:
22174 #ifdef FEAT_FLOAT
22175 	    EMSG(_(e_float_as_string));
22176 	    break;
22177 #endif
22178 	case VAR_STRING:
22179 	    if (varp->vval.v_string != NULL)
22180 		return varp->vval.v_string;
22181 	    return (char_u *)"";
22182 	case VAR_SPECIAL:
22183 	    STRCPY(buf, get_var_special_name(varp->vval.v_number));
22184 	    return buf;
22185 	case VAR_JOB:
22186 #ifdef FEAT_JOB_CHANNEL
22187 	    {
22188 		job_T *job = varp->vval.v_job;
22189 		char  *status;
22190 
22191 		if (job == NULL)
22192 		    return (char_u *)"no process";
22193 		status = job->jv_status == JOB_FAILED ? "fail"
22194 				: job->jv_status == JOB_ENDED ? "dead"
22195 				: "run";
22196 # ifdef UNIX
22197 		vim_snprintf((char *)buf, NUMBUFLEN,
22198 			    "process %ld %s", (long)job->jv_pid, status);
22199 # elif defined(WIN32)
22200 		vim_snprintf((char *)buf, NUMBUFLEN,
22201 			    "process %ld %s",
22202 			    (long)job->jv_proc_info.dwProcessId,
22203 			    status);
22204 # else
22205 		/* fall-back */
22206 		vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status);
22207 # endif
22208 		return buf;
22209 	    }
22210 #endif
22211 	    break;
22212 	case VAR_CHANNEL:
22213 #ifdef FEAT_JOB_CHANNEL
22214 	    {
22215 		channel_T *channel = varp->vval.v_channel;
22216 		char      *status = channel_status(channel);
22217 
22218 		if (channel == NULL)
22219 		    vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status);
22220 		else
22221 		    vim_snprintf((char *)buf, NUMBUFLEN,
22222 				     "channel %d %s", channel->ch_id, status);
22223 		return buf;
22224 	    }
22225 #endif
22226 	    break;
22227 	case VAR_UNKNOWN:
22228 	    EMSG(_("E908: using an invalid value as a String"));
22229 	    break;
22230     }
22231     return NULL;
22232 }
22233 
22234 /*
22235  * Find variable "name" in the list of variables.
22236  * Return a pointer to it if found, NULL if not found.
22237  * Careful: "a:0" variables don't have a name.
22238  * When "htp" is not NULL we are writing to the variable, set "htp" to the
22239  * hashtab_T used.
22240  */
22241     static dictitem_T *
22242 find_var(char_u *name, hashtab_T **htp, int no_autoload)
22243 {
22244     char_u	*varname;
22245     hashtab_T	*ht;
22246 
22247     ht = find_var_ht(name, &varname);
22248     if (htp != NULL)
22249 	*htp = ht;
22250     if (ht == NULL)
22251 	return NULL;
22252     return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL);
22253 }
22254 
22255 /*
22256  * Find variable "varname" in hashtab "ht" with name "htname".
22257  * Returns NULL if not found.
22258  */
22259     static dictitem_T *
22260 find_var_in_ht(
22261     hashtab_T	*ht,
22262     int		htname,
22263     char_u	*varname,
22264     int		no_autoload)
22265 {
22266     hashitem_T	*hi;
22267 
22268     if (*varname == NUL)
22269     {
22270 	/* Must be something like "s:", otherwise "ht" would be NULL. */
22271 	switch (htname)
22272 	{
22273 	    case 's': return &SCRIPT_SV(current_SID)->sv_var;
22274 	    case 'g': return &globvars_var;
22275 	    case 'v': return &vimvars_var;
22276 	    case 'b': return &curbuf->b_bufvar;
22277 	    case 'w': return &curwin->w_winvar;
22278 #ifdef FEAT_WINDOWS
22279 	    case 't': return &curtab->tp_winvar;
22280 #endif
22281 	    case 'l': return current_funccal == NULL
22282 					? NULL : &current_funccal->l_vars_var;
22283 	    case 'a': return current_funccal == NULL
22284 				       ? NULL : &current_funccal->l_avars_var;
22285 	}
22286 	return NULL;
22287     }
22288 
22289     hi = hash_find(ht, varname);
22290     if (HASHITEM_EMPTY(hi))
22291     {
22292 	/* For global variables we may try auto-loading the script.  If it
22293 	 * worked find the variable again.  Don't auto-load a script if it was
22294 	 * loaded already, otherwise it would be loaded every time when
22295 	 * checking if a function name is a Funcref variable. */
22296 	if (ht == &globvarht && !no_autoload)
22297 	{
22298 	    /* Note: script_autoload() may make "hi" invalid. It must either
22299 	     * be obtained again or not used. */
22300 	    if (!script_autoload(varname, FALSE) || aborting())
22301 		return NULL;
22302 	    hi = hash_find(ht, varname);
22303 	}
22304 	if (HASHITEM_EMPTY(hi))
22305 	    return NULL;
22306     }
22307     return HI2DI(hi);
22308 }
22309 
22310 /*
22311  * Find the hashtab used for a variable name.
22312  * Return NULL if the name is not valid.
22313  * Set "varname" to the start of name without ':'.
22314  */
22315     static hashtab_T *
22316 find_var_ht(char_u *name, char_u **varname)
22317 {
22318     hashitem_T	*hi;
22319 
22320     if (name[0] == NUL)
22321 	return NULL;
22322     if (name[1] != ':')
22323     {
22324 	/* The name must not start with a colon or #. */
22325 	if (name[0] == ':' || name[0] == AUTOLOAD_CHAR)
22326 	    return NULL;
22327 	*varname = name;
22328 
22329 	/* "version" is "v:version" in all scopes */
22330 	hi = hash_find(&compat_hashtab, name);
22331 	if (!HASHITEM_EMPTY(hi))
22332 	    return &compat_hashtab;
22333 
22334 	if (current_funccal == NULL)
22335 	    return &globvarht;			/* global variable */
22336 	return &get_funccal()->l_vars.dv_hashtab; /* l: variable */
22337     }
22338     *varname = name + 2;
22339     if (*name == 'g')				/* global variable */
22340 	return &globvarht;
22341     /* There must be no ':' or '#' in the rest of the name, unless g: is used
22342      */
22343     if (vim_strchr(name + 2, ':') != NULL
22344 			       || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL)
22345 	return NULL;
22346     if (*name == 'b')				/* buffer variable */
22347 	return &curbuf->b_vars->dv_hashtab;
22348     if (*name == 'w')				/* window variable */
22349 	return &curwin->w_vars->dv_hashtab;
22350 #ifdef FEAT_WINDOWS
22351     if (*name == 't')				/* tab page variable */
22352 	return &curtab->tp_vars->dv_hashtab;
22353 #endif
22354     if (*name == 'v')				/* v: variable */
22355 	return &vimvarht;
22356     if (*name == 'a' && current_funccal != NULL) /* function argument */
22357 	return &get_funccal()->l_avars.dv_hashtab;
22358     if (*name == 'l' && current_funccal != NULL) /* local function variable */
22359 	return &get_funccal()->l_vars.dv_hashtab;
22360     if (*name == 's'				/* script variable */
22361 	    && current_SID > 0 && current_SID <= ga_scripts.ga_len)
22362 	return &SCRIPT_VARS(current_SID);
22363     return NULL;
22364 }
22365 
22366 /*
22367  * Get function call environment based on bactrace debug level
22368  */
22369     static funccall_T *
22370 get_funccal(void)
22371 {
22372     int		i;
22373     funccall_T	*funccal;
22374     funccall_T	*temp_funccal;
22375 
22376     funccal = current_funccal;
22377     if (debug_backtrace_level > 0)
22378     {
22379 	for (i = 0; i < debug_backtrace_level; i++)
22380 	{
22381 	    temp_funccal = funccal->caller;
22382 	    if (temp_funccal)
22383 		funccal = temp_funccal;
22384 	    else
22385 		/* backtrace level overflow. reset to max */
22386 		debug_backtrace_level = i;
22387 	}
22388     }
22389     return funccal;
22390 }
22391 
22392 /*
22393  * Get the string value of a (global/local) variable.
22394  * Note: see get_tv_string() for how long the pointer remains valid.
22395  * Returns NULL when it doesn't exist.
22396  */
22397     char_u *
22398 get_var_value(char_u *name)
22399 {
22400     dictitem_T	*v;
22401 
22402     v = find_var(name, NULL, FALSE);
22403     if (v == NULL)
22404 	return NULL;
22405     return get_tv_string(&v->di_tv);
22406 }
22407 
22408 /*
22409  * Allocate a new hashtab for a sourced script.  It will be used while
22410  * sourcing this script and when executing functions defined in the script.
22411  */
22412     void
22413 new_script_vars(scid_T id)
22414 {
22415     int		i;
22416     hashtab_T	*ht;
22417     scriptvar_T *sv;
22418 
22419     if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
22420     {
22421 	/* Re-allocating ga_data means that an ht_array pointing to
22422 	 * ht_smallarray becomes invalid.  We can recognize this: ht_mask is
22423 	 * at its init value.  Also reset "v_dict", it's always the same. */
22424 	for (i = 1; i <= ga_scripts.ga_len; ++i)
22425 	{
22426 	    ht = &SCRIPT_VARS(i);
22427 	    if (ht->ht_mask == HT_INIT_SIZE - 1)
22428 		ht->ht_array = ht->ht_smallarray;
22429 	    sv = SCRIPT_SV(i);
22430 	    sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict;
22431 	}
22432 
22433 	while (ga_scripts.ga_len < id)
22434 	{
22435 	    sv = SCRIPT_SV(ga_scripts.ga_len + 1) =
22436 		(scriptvar_T *)alloc_clear(sizeof(scriptvar_T));
22437 	    init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
22438 	    ++ga_scripts.ga_len;
22439 	}
22440     }
22441 }
22442 
22443 /*
22444  * Initialize dictionary "dict" as a scope and set variable "dict_var" to
22445  * point to it.
22446  */
22447     void
22448 init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope)
22449 {
22450     hash_init(&dict->dv_hashtab);
22451     dict->dv_lock = 0;
22452     dict->dv_scope = scope;
22453     dict->dv_refcount = DO_NOT_FREE_CNT;
22454     dict->dv_copyID = 0;
22455     dict_var->di_tv.vval.v_dict = dict;
22456     dict_var->di_tv.v_type = VAR_DICT;
22457     dict_var->di_tv.v_lock = VAR_FIXED;
22458     dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
22459     dict_var->di_key[0] = NUL;
22460 }
22461 
22462 /*
22463  * Unreference a dictionary initialized by init_var_dict().
22464  */
22465     void
22466 unref_var_dict(dict_T *dict)
22467 {
22468     /* Now the dict needs to be freed if no one else is using it, go back to
22469      * normal reference counting. */
22470     dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
22471     dict_unref(dict);
22472 }
22473 
22474 /*
22475  * Clean up a list of internal variables.
22476  * Frees all allocated variables and the value they contain.
22477  * Clears hashtab "ht", does not free it.
22478  */
22479     void
22480 vars_clear(hashtab_T *ht)
22481 {
22482     vars_clear_ext(ht, TRUE);
22483 }
22484 
22485 /*
22486  * Like vars_clear(), but only free the value if "free_val" is TRUE.
22487  */
22488     static void
22489 vars_clear_ext(hashtab_T *ht, int free_val)
22490 {
22491     int		todo;
22492     hashitem_T	*hi;
22493     dictitem_T	*v;
22494 
22495     hash_lock(ht);
22496     todo = (int)ht->ht_used;
22497     for (hi = ht->ht_array; todo > 0; ++hi)
22498     {
22499 	if (!HASHITEM_EMPTY(hi))
22500 	{
22501 	    --todo;
22502 
22503 	    /* Free the variable.  Don't remove it from the hashtab,
22504 	     * ht_array might change then.  hash_clear() takes care of it
22505 	     * later. */
22506 	    v = HI2DI(hi);
22507 	    if (free_val)
22508 		clear_tv(&v->di_tv);
22509 	    if (v->di_flags & DI_FLAGS_ALLOC)
22510 		vim_free(v);
22511 	}
22512     }
22513     hash_clear(ht);
22514     ht->ht_used = 0;
22515 }
22516 
22517 /*
22518  * Delete a variable from hashtab "ht" at item "hi".
22519  * Clear the variable value and free the dictitem.
22520  */
22521     static void
22522 delete_var(hashtab_T *ht, hashitem_T *hi)
22523 {
22524     dictitem_T	*di = HI2DI(hi);
22525 
22526     hash_remove(ht, hi);
22527     clear_tv(&di->di_tv);
22528     vim_free(di);
22529 }
22530 
22531 /*
22532  * List the value of one internal variable.
22533  */
22534     static void
22535 list_one_var(dictitem_T *v, char_u *prefix, int *first)
22536 {
22537     char_u	*tofree;
22538     char_u	*s;
22539     char_u	numbuf[NUMBUFLEN];
22540 
22541     s = echo_string(&v->di_tv, &tofree, numbuf, get_copyID());
22542     list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
22543 					 s == NULL ? (char_u *)"" : s, first);
22544     vim_free(tofree);
22545 }
22546 
22547     static void
22548 list_one_var_a(
22549     char_u	*prefix,
22550     char_u	*name,
22551     int		type,
22552     char_u	*string,
22553     int		*first)  /* when TRUE clear rest of screen and set to FALSE */
22554 {
22555     /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */
22556     msg_start();
22557     msg_puts(prefix);
22558     if (name != NULL)	/* "a:" vars don't have a name stored */
22559 	msg_puts(name);
22560     msg_putchar(' ');
22561     msg_advance(22);
22562     if (type == VAR_NUMBER)
22563 	msg_putchar('#');
22564     else if (type == VAR_FUNC || type == VAR_PARTIAL)
22565 	msg_putchar('*');
22566     else if (type == VAR_LIST)
22567     {
22568 	msg_putchar('[');
22569 	if (*string == '[')
22570 	    ++string;
22571     }
22572     else if (type == VAR_DICT)
22573     {
22574 	msg_putchar('{');
22575 	if (*string == '{')
22576 	    ++string;
22577     }
22578     else
22579 	msg_putchar(' ');
22580 
22581     msg_outtrans(string);
22582 
22583     if (type == VAR_FUNC || type == VAR_PARTIAL)
22584 	msg_puts((char_u *)"()");
22585     if (*first)
22586     {
22587 	msg_clr_eos();
22588 	*first = FALSE;
22589     }
22590 }
22591 
22592 /*
22593  * Set variable "name" to value in "tv".
22594  * If the variable already exists, the value is updated.
22595  * Otherwise the variable is created.
22596  */
22597     static void
22598 set_var(
22599     char_u	*name,
22600     typval_T	*tv,
22601     int		copy)	    /* make copy of value in "tv" */
22602 {
22603     dictitem_T	*v;
22604     char_u	*varname;
22605     hashtab_T	*ht;
22606 
22607     ht = find_var_ht(name, &varname);
22608     if (ht == NULL || *varname == NUL)
22609     {
22610 	EMSG2(_(e_illvar), name);
22611 	return;
22612     }
22613     v = find_var_in_ht(ht, 0, varname, TRUE);
22614 
22615     if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL)
22616 				      && var_check_func_name(name, v == NULL))
22617 	return;
22618 
22619     if (v != NULL)
22620     {
22621 	/* existing variable, need to clear the value */
22622 	if (var_check_ro(v->di_flags, name, FALSE)
22623 			       || tv_check_lock(v->di_tv.v_lock, name, FALSE))
22624 	    return;
22625 
22626 	/*
22627 	 * Handle setting internal v: variables separately where needed to
22628 	 * prevent changing the type.
22629 	 */
22630 	if (ht == &vimvarht)
22631 	{
22632 	    if (v->di_tv.v_type == VAR_STRING)
22633 	    {
22634 		vim_free(v->di_tv.vval.v_string);
22635 		if (copy || tv->v_type != VAR_STRING)
22636 		    v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv));
22637 		else
22638 		{
22639 		    /* Take over the string to avoid an extra alloc/free. */
22640 		    v->di_tv.vval.v_string = tv->vval.v_string;
22641 		    tv->vval.v_string = NULL;
22642 		}
22643 		return;
22644 	    }
22645 	    else if (v->di_tv.v_type == VAR_NUMBER)
22646 	    {
22647 		v->di_tv.vval.v_number = get_tv_number(tv);
22648 		if (STRCMP(varname, "searchforward") == 0)
22649 		    set_search_direction(v->di_tv.vval.v_number ? '/' : '?');
22650 #ifdef FEAT_SEARCH_EXTRA
22651 		else if (STRCMP(varname, "hlsearch") == 0)
22652 		{
22653 		    no_hlsearch = !v->di_tv.vval.v_number;
22654 		    redraw_all_later(SOME_VALID);
22655 		}
22656 #endif
22657 		return;
22658 	    }
22659 	    else if (v->di_tv.v_type != tv->v_type)
22660 		EMSG2(_(e_intern2), "set_var()");
22661 	}
22662 
22663 	clear_tv(&v->di_tv);
22664     }
22665     else		    /* add a new variable */
22666     {
22667 	/* Can't add "v:" variable. */
22668 	if (ht == &vimvarht)
22669 	{
22670 	    EMSG2(_(e_illvar), name);
22671 	    return;
22672 	}
22673 
22674 	/* Make sure the variable name is valid. */
22675 	if (!valid_varname(varname))
22676 	    return;
22677 
22678 	v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
22679 							  + STRLEN(varname)));
22680 	if (v == NULL)
22681 	    return;
22682 	STRCPY(v->di_key, varname);
22683 	if (hash_add(ht, DI2HIKEY(v)) == FAIL)
22684 	{
22685 	    vim_free(v);
22686 	    return;
22687 	}
22688 	v->di_flags = DI_FLAGS_ALLOC;
22689     }
22690 
22691     if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT)
22692 	copy_tv(tv, &v->di_tv);
22693     else
22694     {
22695 	v->di_tv = *tv;
22696 	v->di_tv.v_lock = 0;
22697 	init_tv(tv);
22698     }
22699 }
22700 
22701 /*
22702  * Return TRUE if di_flags "flags" indicates variable "name" is read-only.
22703  * Also give an error message.
22704  */
22705     static int
22706 var_check_ro(int flags, char_u *name, int use_gettext)
22707 {
22708     if (flags & DI_FLAGS_RO)
22709     {
22710 	EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name);
22711 	return TRUE;
22712     }
22713     if ((flags & DI_FLAGS_RO_SBX) && sandbox)
22714     {
22715 	EMSG2(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name);
22716 	return TRUE;
22717     }
22718     return FALSE;
22719 }
22720 
22721 /*
22722  * Return TRUE if di_flags "flags" indicates variable "name" is fixed.
22723  * Also give an error message.
22724  */
22725     static int
22726 var_check_fixed(int flags, char_u *name, int use_gettext)
22727 {
22728     if (flags & DI_FLAGS_FIX)
22729     {
22730 	EMSG2(_("E795: Cannot delete variable %s"),
22731 				      use_gettext ? (char_u *)_(name) : name);
22732 	return TRUE;
22733     }
22734     return FALSE;
22735 }
22736 
22737 /*
22738  * Check if a funcref is assigned to a valid variable name.
22739  * Return TRUE and give an error if not.
22740  */
22741     static int
22742 var_check_func_name(
22743     char_u *name,    /* points to start of variable name */
22744     int    new_var)  /* TRUE when creating the variable */
22745 {
22746     /* Allow for w: b: s: and t:. */
22747     if (!(vim_strchr((char_u *)"wbst", name[0]) != NULL && name[1] == ':')
22748 	    && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
22749 						     ? name[2] : name[0]))
22750     {
22751 	EMSG2(_("E704: Funcref variable name must start with a capital: %s"),
22752 									name);
22753 	return TRUE;
22754     }
22755     /* Don't allow hiding a function.  When "v" is not NULL we might be
22756      * assigning another function to the same var, the type is checked
22757      * below. */
22758     if (new_var && function_exists(name))
22759     {
22760 	EMSG2(_("E705: Variable name conflicts with existing function: %s"),
22761 								    name);
22762 	return TRUE;
22763     }
22764     return FALSE;
22765 }
22766 
22767 /*
22768  * Check if a variable name is valid.
22769  * Return FALSE and give an error if not.
22770  */
22771     static int
22772 valid_varname(char_u *varname)
22773 {
22774     char_u *p;
22775 
22776     for (p = varname; *p != NUL; ++p)
22777 	if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
22778 						   && *p != AUTOLOAD_CHAR)
22779 	{
22780 	    EMSG2(_(e_illvar), varname);
22781 	    return FALSE;
22782 	}
22783     return TRUE;
22784 }
22785 
22786 /*
22787  * Return TRUE if typeval "tv" is set to be locked (immutable).
22788  * Also give an error message, using "name" or _("name") when use_gettext is
22789  * TRUE.
22790  */
22791     static int
22792 tv_check_lock(int lock, char_u *name, int use_gettext)
22793 {
22794     if (lock & VAR_LOCKED)
22795     {
22796 	EMSG2(_("E741: Value is locked: %s"),
22797 				name == NULL ? (char_u *)_("Unknown")
22798 					     : use_gettext ? (char_u *)_(name)
22799 					     : name);
22800 	return TRUE;
22801     }
22802     if (lock & VAR_FIXED)
22803     {
22804 	EMSG2(_("E742: Cannot change value of %s"),
22805 				name == NULL ? (char_u *)_("Unknown")
22806 					     : use_gettext ? (char_u *)_(name)
22807 					     : name);
22808 	return TRUE;
22809     }
22810     return FALSE;
22811 }
22812 
22813 /*
22814  * Copy the values from typval_T "from" to typval_T "to".
22815  * When needed allocates string or increases reference count.
22816  * Does not make a copy of a list or dict but copies the reference!
22817  * It is OK for "from" and "to" to point to the same item.  This is used to
22818  * make a copy later.
22819  */
22820     void
22821 copy_tv(typval_T *from, typval_T *to)
22822 {
22823     to->v_type = from->v_type;
22824     to->v_lock = 0;
22825     switch (from->v_type)
22826     {
22827 	case VAR_NUMBER:
22828 	case VAR_SPECIAL:
22829 	    to->vval.v_number = from->vval.v_number;
22830 	    break;
22831 	case VAR_FLOAT:
22832 #ifdef FEAT_FLOAT
22833 	    to->vval.v_float = from->vval.v_float;
22834 	    break;
22835 #endif
22836 	case VAR_JOB:
22837 #ifdef FEAT_JOB_CHANNEL
22838 	    to->vval.v_job = from->vval.v_job;
22839 	    if (to->vval.v_job != NULL)
22840 		++to->vval.v_job->jv_refcount;
22841 	    break;
22842 #endif
22843 	case VAR_CHANNEL:
22844 #ifdef FEAT_JOB_CHANNEL
22845 	    to->vval.v_channel = from->vval.v_channel;
22846 	    if (to->vval.v_channel != NULL)
22847 		++to->vval.v_channel->ch_refcount;
22848 	    break;
22849 #endif
22850 	case VAR_STRING:
22851 	case VAR_FUNC:
22852 	    if (from->vval.v_string == NULL)
22853 		to->vval.v_string = NULL;
22854 	    else
22855 	    {
22856 		to->vval.v_string = vim_strsave(from->vval.v_string);
22857 		if (from->v_type == VAR_FUNC)
22858 		    func_ref(to->vval.v_string);
22859 	    }
22860 	    break;
22861 	case VAR_PARTIAL:
22862 	    if (from->vval.v_partial == NULL)
22863 		to->vval.v_partial = NULL;
22864 	    else
22865 	    {
22866 		to->vval.v_partial = from->vval.v_partial;
22867 		++to->vval.v_partial->pt_refcount;
22868 	    }
22869 	    break;
22870 	case VAR_LIST:
22871 	    if (from->vval.v_list == NULL)
22872 		to->vval.v_list = NULL;
22873 	    else
22874 	    {
22875 		to->vval.v_list = from->vval.v_list;
22876 		++to->vval.v_list->lv_refcount;
22877 	    }
22878 	    break;
22879 	case VAR_DICT:
22880 	    if (from->vval.v_dict == NULL)
22881 		to->vval.v_dict = NULL;
22882 	    else
22883 	    {
22884 		to->vval.v_dict = from->vval.v_dict;
22885 		++to->vval.v_dict->dv_refcount;
22886 	    }
22887 	    break;
22888 	case VAR_UNKNOWN:
22889 	    EMSG2(_(e_intern2), "copy_tv(UNKNOWN)");
22890 	    break;
22891     }
22892 }
22893 
22894 /*
22895  * Make a copy of an item.
22896  * Lists and Dictionaries are also copied.  A deep copy if "deep" is set.
22897  * For deepcopy() "copyID" is zero for a full copy or the ID for when a
22898  * reference to an already copied list/dict can be used.
22899  * Returns FAIL or OK.
22900  */
22901     static int
22902 item_copy(
22903     typval_T	*from,
22904     typval_T	*to,
22905     int		deep,
22906     int		copyID)
22907 {
22908     static int	recurse = 0;
22909     int		ret = OK;
22910 
22911     if (recurse >= DICT_MAXNEST)
22912     {
22913 	EMSG(_("E698: variable nested too deep for making a copy"));
22914 	return FAIL;
22915     }
22916     ++recurse;
22917 
22918     switch (from->v_type)
22919     {
22920 	case VAR_NUMBER:
22921 	case VAR_FLOAT:
22922 	case VAR_STRING:
22923 	case VAR_FUNC:
22924 	case VAR_PARTIAL:
22925 	case VAR_SPECIAL:
22926 	case VAR_JOB:
22927 	case VAR_CHANNEL:
22928 	    copy_tv(from, to);
22929 	    break;
22930 	case VAR_LIST:
22931 	    to->v_type = VAR_LIST;
22932 	    to->v_lock = 0;
22933 	    if (from->vval.v_list == NULL)
22934 		to->vval.v_list = NULL;
22935 	    else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID)
22936 	    {
22937 		/* use the copy made earlier */
22938 		to->vval.v_list = from->vval.v_list->lv_copylist;
22939 		++to->vval.v_list->lv_refcount;
22940 	    }
22941 	    else
22942 		to->vval.v_list = list_copy(from->vval.v_list, deep, copyID);
22943 	    if (to->vval.v_list == NULL)
22944 		ret = FAIL;
22945 	    break;
22946 	case VAR_DICT:
22947 	    to->v_type = VAR_DICT;
22948 	    to->v_lock = 0;
22949 	    if (from->vval.v_dict == NULL)
22950 		to->vval.v_dict = NULL;
22951 	    else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID)
22952 	    {
22953 		/* use the copy made earlier */
22954 		to->vval.v_dict = from->vval.v_dict->dv_copydict;
22955 		++to->vval.v_dict->dv_refcount;
22956 	    }
22957 	    else
22958 		to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID);
22959 	    if (to->vval.v_dict == NULL)
22960 		ret = FAIL;
22961 	    break;
22962 	case VAR_UNKNOWN:
22963 	    EMSG2(_(e_intern2), "item_copy(UNKNOWN)");
22964 	    ret = FAIL;
22965     }
22966     --recurse;
22967     return ret;
22968 }
22969 
22970 /*
22971  * ":echo expr1 ..."	print each argument separated with a space, add a
22972  *			newline at the end.
22973  * ":echon expr1 ..."	print each argument plain.
22974  */
22975     void
22976 ex_echo(exarg_T *eap)
22977 {
22978     char_u	*arg = eap->arg;
22979     typval_T	rettv;
22980     char_u	*tofree;
22981     char_u	*p;
22982     int		needclr = TRUE;
22983     int		atstart = TRUE;
22984     char_u	numbuf[NUMBUFLEN];
22985 
22986     if (eap->skip)
22987 	++emsg_skip;
22988     while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
22989     {
22990 	/* If eval1() causes an error message the text from the command may
22991 	 * still need to be cleared. E.g., "echo 22,44". */
22992 	need_clr_eos = needclr;
22993 
22994 	p = arg;
22995 	if (eval1(&arg, &rettv, !eap->skip) == FAIL)
22996 	{
22997 	    /*
22998 	     * Report the invalid expression unless the expression evaluation
22999 	     * has been cancelled due to an aborting error, an interrupt, or an
23000 	     * exception.
23001 	     */
23002 	    if (!aborting())
23003 		EMSG2(_(e_invexpr2), p);
23004 	    need_clr_eos = FALSE;
23005 	    break;
23006 	}
23007 	need_clr_eos = FALSE;
23008 
23009 	if (!eap->skip)
23010 	{
23011 	    if (atstart)
23012 	    {
23013 		atstart = FALSE;
23014 		/* Call msg_start() after eval1(), evaluating the expression
23015 		 * may cause a message to appear. */
23016 		if (eap->cmdidx == CMD_echo)
23017 		{
23018 		    /* Mark the saved text as finishing the line, so that what
23019 		     * follows is displayed on a new line when scrolling back
23020 		     * at the more prompt. */
23021 		    msg_sb_eol();
23022 		    msg_start();
23023 		}
23024 	    }
23025 	    else if (eap->cmdidx == CMD_echo)
23026 		msg_puts_attr((char_u *)" ", echo_attr);
23027 	    p = echo_string(&rettv, &tofree, numbuf, get_copyID());
23028 	    if (p != NULL)
23029 		for ( ; *p != NUL && !got_int; ++p)
23030 		{
23031 		    if (*p == '\n' || *p == '\r' || *p == TAB)
23032 		    {
23033 			if (*p != TAB && needclr)
23034 			{
23035 			    /* remove any text still there from the command */
23036 			    msg_clr_eos();
23037 			    needclr = FALSE;
23038 			}
23039 			msg_putchar_attr(*p, echo_attr);
23040 		    }
23041 		    else
23042 		    {
23043 #ifdef FEAT_MBYTE
23044 			if (has_mbyte)
23045 			{
23046 			    int i = (*mb_ptr2len)(p);
23047 
23048 			    (void)msg_outtrans_len_attr(p, i, echo_attr);
23049 			    p += i - 1;
23050 			}
23051 			else
23052 #endif
23053 			    (void)msg_outtrans_len_attr(p, 1, echo_attr);
23054 		    }
23055 		}
23056 	    vim_free(tofree);
23057 	}
23058 	clear_tv(&rettv);
23059 	arg = skipwhite(arg);
23060     }
23061     eap->nextcmd = check_nextcmd(arg);
23062 
23063     if (eap->skip)
23064 	--emsg_skip;
23065     else
23066     {
23067 	/* remove text that may still be there from the command */
23068 	if (needclr)
23069 	    msg_clr_eos();
23070 	if (eap->cmdidx == CMD_echo)
23071 	    msg_end();
23072     }
23073 }
23074 
23075 /*
23076  * ":echohl {name}".
23077  */
23078     void
23079 ex_echohl(exarg_T *eap)
23080 {
23081     int		id;
23082 
23083     id = syn_name2id(eap->arg);
23084     if (id == 0)
23085 	echo_attr = 0;
23086     else
23087 	echo_attr = syn_id2attr(id);
23088 }
23089 
23090 /*
23091  * ":execute expr1 ..."	execute the result of an expression.
23092  * ":echomsg expr1 ..."	Print a message
23093  * ":echoerr expr1 ..."	Print an error
23094  * Each gets spaces around each argument and a newline at the end for
23095  * echo commands
23096  */
23097     void
23098 ex_execute(exarg_T *eap)
23099 {
23100     char_u	*arg = eap->arg;
23101     typval_T	rettv;
23102     int		ret = OK;
23103     char_u	*p;
23104     garray_T	ga;
23105     int		len;
23106     int		save_did_emsg;
23107 
23108     ga_init2(&ga, 1, 80);
23109 
23110     if (eap->skip)
23111 	++emsg_skip;
23112     while (*arg != NUL && *arg != '|' && *arg != '\n')
23113     {
23114 	p = arg;
23115 	if (eval1(&arg, &rettv, !eap->skip) == FAIL)
23116 	{
23117 	    /*
23118 	     * Report the invalid expression unless the expression evaluation
23119 	     * has been cancelled due to an aborting error, an interrupt, or an
23120 	     * exception.
23121 	     */
23122 	    if (!aborting())
23123 		EMSG2(_(e_invexpr2), p);
23124 	    ret = FAIL;
23125 	    break;
23126 	}
23127 
23128 	if (!eap->skip)
23129 	{
23130 	    p = get_tv_string(&rettv);
23131 	    len = (int)STRLEN(p);
23132 	    if (ga_grow(&ga, len + 2) == FAIL)
23133 	    {
23134 		clear_tv(&rettv);
23135 		ret = FAIL;
23136 		break;
23137 	    }
23138 	    if (ga.ga_len)
23139 		((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
23140 	    STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
23141 	    ga.ga_len += len;
23142 	}
23143 
23144 	clear_tv(&rettv);
23145 	arg = skipwhite(arg);
23146     }
23147 
23148     if (ret != FAIL && ga.ga_data != NULL)
23149     {
23150 	if (eap->cmdidx == CMD_echomsg)
23151 	{
23152 	    MSG_ATTR(ga.ga_data, echo_attr);
23153 	    out_flush();
23154 	}
23155 	else if (eap->cmdidx == CMD_echoerr)
23156 	{
23157 	    /* We don't want to abort following commands, restore did_emsg. */
23158 	    save_did_emsg = did_emsg;
23159 	    EMSG((char_u *)ga.ga_data);
23160 	    if (!force_abort)
23161 		did_emsg = save_did_emsg;
23162 	}
23163 	else if (eap->cmdidx == CMD_execute)
23164 	    do_cmdline((char_u *)ga.ga_data,
23165 		       eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
23166     }
23167 
23168     ga_clear(&ga);
23169 
23170     if (eap->skip)
23171 	--emsg_skip;
23172 
23173     eap->nextcmd = check_nextcmd(arg);
23174 }
23175 
23176 /*
23177  * Skip over the name of an option: "&option", "&g:option" or "&l:option".
23178  * "arg" points to the "&" or '+' when called, to "option" when returning.
23179  * Returns NULL when no option name found.  Otherwise pointer to the char
23180  * after the option name.
23181  */
23182     static char_u *
23183 find_option_end(char_u **arg, int *opt_flags)
23184 {
23185     char_u	*p = *arg;
23186 
23187     ++p;
23188     if (*p == 'g' && p[1] == ':')
23189     {
23190 	*opt_flags = OPT_GLOBAL;
23191 	p += 2;
23192     }
23193     else if (*p == 'l' && p[1] == ':')
23194     {
23195 	*opt_flags = OPT_LOCAL;
23196 	p += 2;
23197     }
23198     else
23199 	*opt_flags = 0;
23200 
23201     if (!ASCII_ISALPHA(*p))
23202 	return NULL;
23203     *arg = p;
23204 
23205     if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
23206 	p += 4;	    /* termcap option */
23207     else
23208 	while (ASCII_ISALPHA(*p))
23209 	    ++p;
23210     return p;
23211 }
23212 
23213 /*
23214  * ":function"
23215  */
23216     void
23217 ex_function(exarg_T *eap)
23218 {
23219     char_u	*theline;
23220     int		i;
23221     int		j;
23222     int		c;
23223     int		saved_did_emsg;
23224     int		saved_wait_return = need_wait_return;
23225     char_u	*name = NULL;
23226     char_u	*p;
23227     char_u	*arg;
23228     char_u	*line_arg = NULL;
23229     garray_T	newargs;
23230     garray_T	newlines;
23231     int		varargs = FALSE;
23232     int		mustend = FALSE;
23233     int		flags = 0;
23234     ufunc_T	*fp;
23235     int		indent;
23236     int		nesting;
23237     char_u	*skip_until = NULL;
23238     dictitem_T	*v;
23239     funcdict_T	fudi;
23240     static int	func_nr = 0;	    /* number for nameless function */
23241     int		paren;
23242     hashtab_T	*ht;
23243     int		todo;
23244     hashitem_T	*hi;
23245     int		sourcing_lnum_off;
23246 
23247     /*
23248      * ":function" without argument: list functions.
23249      */
23250     if (ends_excmd(*eap->arg))
23251     {
23252 	if (!eap->skip)
23253 	{
23254 	    todo = (int)func_hashtab.ht_used;
23255 	    for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
23256 	    {
23257 		if (!HASHITEM_EMPTY(hi))
23258 		{
23259 		    --todo;
23260 		    fp = HI2UF(hi);
23261 		    if (!isdigit(*fp->uf_name))
23262 			list_func_head(fp, FALSE);
23263 		}
23264 	    }
23265 	}
23266 	eap->nextcmd = check_nextcmd(eap->arg);
23267 	return;
23268     }
23269 
23270     /*
23271      * ":function /pat": list functions matching pattern.
23272      */
23273     if (*eap->arg == '/')
23274     {
23275 	p = skip_regexp(eap->arg + 1, '/', TRUE, NULL);
23276 	if (!eap->skip)
23277 	{
23278 	    regmatch_T	regmatch;
23279 
23280 	    c = *p;
23281 	    *p = NUL;
23282 	    regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC);
23283 	    *p = c;
23284 	    if (regmatch.regprog != NULL)
23285 	    {
23286 		regmatch.rm_ic = p_ic;
23287 
23288 		todo = (int)func_hashtab.ht_used;
23289 		for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
23290 		{
23291 		    if (!HASHITEM_EMPTY(hi))
23292 		    {
23293 			--todo;
23294 			fp = HI2UF(hi);
23295 			if (!isdigit(*fp->uf_name)
23296 				    && vim_regexec(&regmatch, fp->uf_name, 0))
23297 			    list_func_head(fp, FALSE);
23298 		    }
23299 		}
23300 		vim_regfree(regmatch.regprog);
23301 	    }
23302 	}
23303 	if (*p == '/')
23304 	    ++p;
23305 	eap->nextcmd = check_nextcmd(p);
23306 	return;
23307     }
23308 
23309     /*
23310      * Get the function name.  There are these situations:
23311      * func	    normal function name
23312      *		    "name" == func, "fudi.fd_dict" == NULL
23313      * dict.func    new dictionary entry
23314      *		    "name" == NULL, "fudi.fd_dict" set,
23315      *		    "fudi.fd_di" == NULL, "fudi.fd_newkey" == func
23316      * dict.func    existing dict entry with a Funcref
23317      *		    "name" == func, "fudi.fd_dict" set,
23318      *		    "fudi.fd_di" set, "fudi.fd_newkey" == NULL
23319      * dict.func    existing dict entry that's not a Funcref
23320      *		    "name" == NULL, "fudi.fd_dict" set,
23321      *		    "fudi.fd_di" set, "fudi.fd_newkey" == NULL
23322      * s:func	    script-local function name
23323      * g:func	    global function name, same as "func"
23324      */
23325     p = eap->arg;
23326     name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
23327     paren = (vim_strchr(p, '(') != NULL);
23328     if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
23329     {
23330 	/*
23331 	 * Return on an invalid expression in braces, unless the expression
23332 	 * evaluation has been cancelled due to an aborting error, an
23333 	 * interrupt, or an exception.
23334 	 */
23335 	if (!aborting())
23336 	{
23337 	    if (!eap->skip && fudi.fd_newkey != NULL)
23338 		EMSG2(_(e_dictkey), fudi.fd_newkey);
23339 	    vim_free(fudi.fd_newkey);
23340 	    return;
23341 	}
23342 	else
23343 	    eap->skip = TRUE;
23344     }
23345 
23346     /* An error in a function call during evaluation of an expression in magic
23347      * braces should not cause the function not to be defined. */
23348     saved_did_emsg = did_emsg;
23349     did_emsg = FALSE;
23350 
23351     /*
23352      * ":function func" with only function name: list function.
23353      */
23354     if (!paren)
23355     {
23356 	if (!ends_excmd(*skipwhite(p)))
23357 	{
23358 	    EMSG(_(e_trailing));
23359 	    goto ret_free;
23360 	}
23361 	eap->nextcmd = check_nextcmd(p);
23362 	if (eap->nextcmd != NULL)
23363 	    *p = NUL;
23364 	if (!eap->skip && !got_int)
23365 	{
23366 	    fp = find_func(name);
23367 	    if (fp != NULL)
23368 	    {
23369 		list_func_head(fp, TRUE);
23370 		for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j)
23371 		{
23372 		    if (FUNCLINE(fp, j) == NULL)
23373 			continue;
23374 		    msg_putchar('\n');
23375 		    msg_outnum((long)(j + 1));
23376 		    if (j < 9)
23377 			msg_putchar(' ');
23378 		    if (j < 99)
23379 			msg_putchar(' ');
23380 		    msg_prt_line(FUNCLINE(fp, j), FALSE);
23381 		    out_flush();	/* show a line at a time */
23382 		    ui_breakcheck();
23383 		}
23384 		if (!got_int)
23385 		{
23386 		    msg_putchar('\n');
23387 		    msg_puts((char_u *)"   endfunction");
23388 		}
23389 	    }
23390 	    else
23391 		emsg_funcname(N_("E123: Undefined function: %s"), name);
23392 	}
23393 	goto ret_free;
23394     }
23395 
23396     /*
23397      * ":function name(arg1, arg2)" Define function.
23398      */
23399     p = skipwhite(p);
23400     if (*p != '(')
23401     {
23402 	if (!eap->skip)
23403 	{
23404 	    EMSG2(_("E124: Missing '(': %s"), eap->arg);
23405 	    goto ret_free;
23406 	}
23407 	/* attempt to continue by skipping some text */
23408 	if (vim_strchr(p, '(') != NULL)
23409 	    p = vim_strchr(p, '(');
23410     }
23411     p = skipwhite(p + 1);
23412 
23413     ga_init2(&newargs, (int)sizeof(char_u *), 3);
23414     ga_init2(&newlines, (int)sizeof(char_u *), 3);
23415 
23416     if (!eap->skip)
23417     {
23418 	/* Check the name of the function.  Unless it's a dictionary function
23419 	 * (that we are overwriting). */
23420 	if (name != NULL)
23421 	    arg = name;
23422 	else
23423 	    arg = fudi.fd_newkey;
23424 	if (arg != NULL && (fudi.fd_di == NULL
23425 				     || fudi.fd_di->di_tv.v_type != VAR_FUNC))
23426 	{
23427 	    if (*arg == K_SPECIAL)
23428 		j = 3;
23429 	    else
23430 		j = 0;
23431 	    while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
23432 						      : eval_isnamec(arg[j])))
23433 		++j;
23434 	    if (arg[j] != NUL)
23435 		emsg_funcname((char *)e_invarg2, arg);
23436 	}
23437 	/* Disallow using the g: dict. */
23438 	if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE)
23439 	    EMSG(_("E862: Cannot use g: here"));
23440     }
23441 
23442     /*
23443      * Isolate the arguments: "arg1, arg2, ...)"
23444      */
23445     while (*p != ')')
23446     {
23447 	if (p[0] == '.' && p[1] == '.' && p[2] == '.')
23448 	{
23449 	    varargs = TRUE;
23450 	    p += 3;
23451 	    mustend = TRUE;
23452 	}
23453 	else
23454 	{
23455 	    arg = p;
23456 	    while (ASCII_ISALNUM(*p) || *p == '_')
23457 		++p;
23458 	    if (arg == p || isdigit(*arg)
23459 		    || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
23460 		    || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0))
23461 	    {
23462 		if (!eap->skip)
23463 		    EMSG2(_("E125: Illegal argument: %s"), arg);
23464 		break;
23465 	    }
23466 	    if (ga_grow(&newargs, 1) == FAIL)
23467 		goto erret;
23468 	    c = *p;
23469 	    *p = NUL;
23470 	    arg = vim_strsave(arg);
23471 	    if (arg == NULL)
23472 		goto erret;
23473 
23474 	    /* Check for duplicate argument name. */
23475 	    for (i = 0; i < newargs.ga_len; ++i)
23476 		if (STRCMP(((char_u **)(newargs.ga_data))[i], arg) == 0)
23477 		{
23478 		    EMSG2(_("E853: Duplicate argument name: %s"), arg);
23479 		    vim_free(arg);
23480 		    goto erret;
23481 		}
23482 
23483 	    ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
23484 	    *p = c;
23485 	    newargs.ga_len++;
23486 	    if (*p == ',')
23487 		++p;
23488 	    else
23489 		mustend = TRUE;
23490 	}
23491 	p = skipwhite(p);
23492 	if (mustend && *p != ')')
23493 	{
23494 	    if (!eap->skip)
23495 		EMSG2(_(e_invarg2), eap->arg);
23496 	    break;
23497 	}
23498     }
23499     if (*p != ')')
23500 	goto erret;
23501     ++p;	/* skip the ')' */
23502 
23503     /* find extra arguments "range", "dict" and "abort" */
23504     for (;;)
23505     {
23506 	p = skipwhite(p);
23507 	if (STRNCMP(p, "range", 5) == 0)
23508 	{
23509 	    flags |= FC_RANGE;
23510 	    p += 5;
23511 	}
23512 	else if (STRNCMP(p, "dict", 4) == 0)
23513 	{
23514 	    flags |= FC_DICT;
23515 	    p += 4;
23516 	}
23517 	else if (STRNCMP(p, "abort", 5) == 0)
23518 	{
23519 	    flags |= FC_ABORT;
23520 	    p += 5;
23521 	}
23522 	else
23523 	    break;
23524     }
23525 
23526     /* When there is a line break use what follows for the function body.
23527      * Makes 'exe "func Test()\n...\nendfunc"' work. */
23528     if (*p == '\n')
23529 	line_arg = p + 1;
23530     else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg)
23531 	EMSG(_(e_trailing));
23532 
23533     /*
23534      * Read the body of the function, until ":endfunction" is found.
23535      */
23536     if (KeyTyped)
23537     {
23538 	/* Check if the function already exists, don't let the user type the
23539 	 * whole function before telling him it doesn't work!  For a script we
23540 	 * need to skip the body to be able to find what follows. */
23541 	if (!eap->skip && !eap->forceit)
23542 	{
23543 	    if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL)
23544 		EMSG(_(e_funcdict));
23545 	    else if (name != NULL && find_func(name) != NULL)
23546 		emsg_funcname(e_funcexts, name);
23547 	}
23548 
23549 	if (!eap->skip && did_emsg)
23550 	    goto erret;
23551 
23552 	msg_putchar('\n');	    /* don't overwrite the function name */
23553 	cmdline_row = msg_row;
23554     }
23555 
23556     indent = 2;
23557     nesting = 0;
23558     for (;;)
23559     {
23560 	if (KeyTyped)
23561 	{
23562 	    msg_scroll = TRUE;
23563 	    saved_wait_return = FALSE;
23564 	}
23565 	need_wait_return = FALSE;
23566 	sourcing_lnum_off = sourcing_lnum;
23567 
23568 	if (line_arg != NULL)
23569 	{
23570 	    /* Use eap->arg, split up in parts by line breaks. */
23571 	    theline = line_arg;
23572 	    p = vim_strchr(theline, '\n');
23573 	    if (p == NULL)
23574 		line_arg += STRLEN(line_arg);
23575 	    else
23576 	    {
23577 		*p = NUL;
23578 		line_arg = p + 1;
23579 	    }
23580 	}
23581 	else if (eap->getline == NULL)
23582 	    theline = getcmdline(':', 0L, indent);
23583 	else
23584 	    theline = eap->getline(':', eap->cookie, indent);
23585 	if (KeyTyped)
23586 	    lines_left = Rows - 1;
23587 	if (theline == NULL)
23588 	{
23589 	    EMSG(_("E126: Missing :endfunction"));
23590 	    goto erret;
23591 	}
23592 
23593 	/* Detect line continuation: sourcing_lnum increased more than one. */
23594 	if (sourcing_lnum > sourcing_lnum_off + 1)
23595 	    sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1;
23596 	else
23597 	    sourcing_lnum_off = 0;
23598 
23599 	if (skip_until != NULL)
23600 	{
23601 	    /* between ":append" and "." and between ":python <<EOF" and "EOF"
23602 	     * don't check for ":endfunc". */
23603 	    if (STRCMP(theline, skip_until) == 0)
23604 	    {
23605 		vim_free(skip_until);
23606 		skip_until = NULL;
23607 	    }
23608 	}
23609 	else
23610 	{
23611 	    /* skip ':' and blanks*/
23612 	    for (p = theline; vim_iswhite(*p) || *p == ':'; ++p)
23613 		;
23614 
23615 	    /* Check for "endfunction". */
23616 	    if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0)
23617 	    {
23618 		if (line_arg == NULL)
23619 		    vim_free(theline);
23620 		break;
23621 	    }
23622 
23623 	    /* Increase indent inside "if", "while", "for" and "try", decrease
23624 	     * at "end". */
23625 	    if (indent > 2 && STRNCMP(p, "end", 3) == 0)
23626 		indent -= 2;
23627 	    else if (STRNCMP(p, "if", 2) == 0
23628 		    || STRNCMP(p, "wh", 2) == 0
23629 		    || STRNCMP(p, "for", 3) == 0
23630 		    || STRNCMP(p, "try", 3) == 0)
23631 		indent += 2;
23632 
23633 	    /* Check for defining a function inside this function. */
23634 	    if (checkforcmd(&p, "function", 2))
23635 	    {
23636 		if (*p == '!')
23637 		    p = skipwhite(p + 1);
23638 		p += eval_fname_script(p);
23639 		vim_free(trans_function_name(&p, TRUE, 0, NULL, NULL));
23640 		if (*skipwhite(p) == '(')
23641 		{
23642 		    ++nesting;
23643 		    indent += 2;
23644 		}
23645 	    }
23646 
23647 	    /* Check for ":append" or ":insert". */
23648 	    p = skip_range(p, NULL);
23649 	    if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
23650 		    || (p[0] == 'i'
23651 			&& (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
23652 				&& (!ASCII_ISALPHA(p[2]) || (p[2] == 's'))))))
23653 		skip_until = vim_strsave((char_u *)".");
23654 
23655 	    /* Check for ":python <<EOF", ":tcl <<EOF", etc. */
23656 	    arg = skipwhite(skiptowhite(p));
23657 	    if (arg[0] == '<' && arg[1] =='<'
23658 		    && ((p[0] == 'p' && p[1] == 'y'
23659 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 't'))
23660 			|| (p[0] == 'p' && p[1] == 'e'
23661 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
23662 			|| (p[0] == 't' && p[1] == 'c'
23663 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'l'))
23664 			|| (p[0] == 'l' && p[1] == 'u' && p[2] == 'a'
23665 				    && !ASCII_ISALPHA(p[3]))
23666 			|| (p[0] == 'r' && p[1] == 'u' && p[2] == 'b'
23667 				    && (!ASCII_ISALPHA(p[3]) || p[3] == 'y'))
23668 			|| (p[0] == 'm' && p[1] == 'z'
23669 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 's'))
23670 			))
23671 	    {
23672 		/* ":python <<" continues until a dot, like ":append" */
23673 		p = skipwhite(arg + 2);
23674 		if (*p == NUL)
23675 		    skip_until = vim_strsave((char_u *)".");
23676 		else
23677 		    skip_until = vim_strsave(p);
23678 	    }
23679 	}
23680 
23681 	/* Add the line to the function. */
23682 	if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL)
23683 	{
23684 	    if (line_arg == NULL)
23685 		vim_free(theline);
23686 	    goto erret;
23687 	}
23688 
23689 	/* Copy the line to newly allocated memory.  get_one_sourceline()
23690 	 * allocates 250 bytes per line, this saves 80% on average.  The cost
23691 	 * is an extra alloc/free. */
23692 	p = vim_strsave(theline);
23693 	if (p != NULL)
23694 	{
23695 	    if (line_arg == NULL)
23696 		vim_free(theline);
23697 	    theline = p;
23698 	}
23699 
23700 	((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline;
23701 
23702 	/* Add NULL lines for continuation lines, so that the line count is
23703 	 * equal to the index in the growarray.   */
23704 	while (sourcing_lnum_off-- > 0)
23705 	    ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL;
23706 
23707 	/* Check for end of eap->arg. */
23708 	if (line_arg != NULL && *line_arg == NUL)
23709 	    line_arg = NULL;
23710     }
23711 
23712     /* Don't define the function when skipping commands or when an error was
23713      * detected. */
23714     if (eap->skip || did_emsg)
23715 	goto erret;
23716 
23717     /*
23718      * If there are no errors, add the function
23719      */
23720     if (fudi.fd_dict == NULL)
23721     {
23722 	v = find_var(name, &ht, FALSE);
23723 	if (v != NULL && v->di_tv.v_type == VAR_FUNC)
23724 	{
23725 	    emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
23726 									name);
23727 	    goto erret;
23728 	}
23729 
23730 	fp = find_func(name);
23731 	if (fp != NULL)
23732 	{
23733 	    if (!eap->forceit)
23734 	    {
23735 		emsg_funcname(e_funcexts, name);
23736 		goto erret;
23737 	    }
23738 	    if (fp->uf_calls > 0)
23739 	    {
23740 		emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
23741 									name);
23742 		goto erret;
23743 	    }
23744 	    /* redefine existing function */
23745 	    ga_clear_strings(&(fp->uf_args));
23746 	    ga_clear_strings(&(fp->uf_lines));
23747 	    vim_free(name);
23748 	    name = NULL;
23749 	}
23750     }
23751     else
23752     {
23753 	char	numbuf[20];
23754 
23755 	fp = NULL;
23756 	if (fudi.fd_newkey == NULL && !eap->forceit)
23757 	{
23758 	    EMSG(_(e_funcdict));
23759 	    goto erret;
23760 	}
23761 	if (fudi.fd_di == NULL)
23762 	{
23763 	    /* Can't add a function to a locked dictionary */
23764 	    if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg, FALSE))
23765 		goto erret;
23766 	}
23767 	    /* Can't change an existing function if it is locked */
23768 	else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, FALSE))
23769 	    goto erret;
23770 
23771 	/* Give the function a sequential number.  Can only be used with a
23772 	 * Funcref! */
23773 	vim_free(name);
23774 	sprintf(numbuf, "%d", ++func_nr);
23775 	name = vim_strsave((char_u *)numbuf);
23776 	if (name == NULL)
23777 	    goto erret;
23778     }
23779 
23780     if (fp == NULL)
23781     {
23782 	if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL)
23783 	{
23784 	    int	    slen, plen;
23785 	    char_u  *scriptname;
23786 
23787 	    /* Check that the autoload name matches the script name. */
23788 	    j = FAIL;
23789 	    if (sourcing_name != NULL)
23790 	    {
23791 		scriptname = autoload_name(name);
23792 		if (scriptname != NULL)
23793 		{
23794 		    p = vim_strchr(scriptname, '/');
23795 		    plen = (int)STRLEN(p);
23796 		    slen = (int)STRLEN(sourcing_name);
23797 		    if (slen > plen && fnamecmp(p,
23798 					    sourcing_name + slen - plen) == 0)
23799 			j = OK;
23800 		    vim_free(scriptname);
23801 		}
23802 	    }
23803 	    if (j == FAIL)
23804 	    {
23805 		EMSG2(_("E746: Function name does not match script file name: %s"), name);
23806 		goto erret;
23807 	    }
23808 	}
23809 
23810 	fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name)));
23811 	if (fp == NULL)
23812 	    goto erret;
23813 
23814 	if (fudi.fd_dict != NULL)
23815 	{
23816 	    if (fudi.fd_di == NULL)
23817 	    {
23818 		/* add new dict entry */
23819 		fudi.fd_di = dictitem_alloc(fudi.fd_newkey);
23820 		if (fudi.fd_di == NULL)
23821 		{
23822 		    vim_free(fp);
23823 		    goto erret;
23824 		}
23825 		if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL)
23826 		{
23827 		    vim_free(fudi.fd_di);
23828 		    vim_free(fp);
23829 		    goto erret;
23830 		}
23831 	    }
23832 	    else
23833 		/* overwrite existing dict entry */
23834 		clear_tv(&fudi.fd_di->di_tv);
23835 	    fudi.fd_di->di_tv.v_type = VAR_FUNC;
23836 	    fudi.fd_di->di_tv.v_lock = 0;
23837 	    fudi.fd_di->di_tv.vval.v_string = vim_strsave(name);
23838 	    fp->uf_refcount = 1;
23839 
23840 	    /* behave like "dict" was used */
23841 	    flags |= FC_DICT;
23842 	}
23843 
23844 	/* insert the new function in the function list */
23845 	STRCPY(fp->uf_name, name);
23846 	if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL)
23847 	{
23848 	    vim_free(fp);
23849 	    goto erret;
23850 	}
23851     }
23852     fp->uf_args = newargs;
23853     fp->uf_lines = newlines;
23854 #ifdef FEAT_PROFILE
23855     fp->uf_tml_count = NULL;
23856     fp->uf_tml_total = NULL;
23857     fp->uf_tml_self = NULL;
23858     fp->uf_profiling = FALSE;
23859     if (prof_def_func())
23860 	func_do_profile(fp);
23861 #endif
23862     fp->uf_varargs = varargs;
23863     fp->uf_flags = flags;
23864     fp->uf_calls = 0;
23865     fp->uf_script_ID = current_SID;
23866     goto ret_free;
23867 
23868 erret:
23869     ga_clear_strings(&newargs);
23870     ga_clear_strings(&newlines);
23871 ret_free:
23872     vim_free(skip_until);
23873     vim_free(fudi.fd_newkey);
23874     vim_free(name);
23875     did_emsg |= saved_did_emsg;
23876     need_wait_return |= saved_wait_return;
23877 }
23878 
23879 /*
23880  * Get a function name, translating "<SID>" and "<SNR>".
23881  * Also handles a Funcref in a List or Dictionary.
23882  * Returns the function name in allocated memory, or NULL for failure.
23883  * flags:
23884  * TFN_INT:	    internal function name OK
23885  * TFN_QUIET:	    be quiet
23886  * TFN_NO_AUTOLOAD: do not use script autoloading
23887  * Advances "pp" to just after the function name (if no error).
23888  */
23889     static char_u *
23890 trans_function_name(
23891     char_u	**pp,
23892     int		skip,		/* only find the end, don't evaluate */
23893     int		flags,
23894     funcdict_T	*fdp,		/* return: info about dictionary used */
23895     partial_T	**partial)	/* return: partial of a FuncRef */
23896 {
23897     char_u	*name = NULL;
23898     char_u	*start;
23899     char_u	*end;
23900     int		lead;
23901     char_u	sid_buf[20];
23902     int		len;
23903     lval_T	lv;
23904 
23905     if (fdp != NULL)
23906 	vim_memset(fdp, 0, sizeof(funcdict_T));
23907     start = *pp;
23908 
23909     /* Check for hard coded <SNR>: already translated function ID (from a user
23910      * command). */
23911     if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA
23912 						   && (*pp)[2] == (int)KE_SNR)
23913     {
23914 	*pp += 3;
23915 	len = get_id_len(pp) + 3;
23916 	return vim_strnsave(start, len);
23917     }
23918 
23919     /* A name starting with "<SID>" or "<SNR>" is local to a script.  But
23920      * don't skip over "s:", get_lval() needs it for "s:dict.func". */
23921     lead = eval_fname_script(start);
23922     if (lead > 2)
23923 	start += lead;
23924 
23925     /* Note that TFN_ flags use the same values as GLV_ flags. */
23926     end = get_lval(start, NULL, &lv, FALSE, skip, flags,
23927 					      lead > 2 ? 0 : FNE_CHECK_START);
23928     if (end == start)
23929     {
23930 	if (!skip)
23931 	    EMSG(_("E129: Function name required"));
23932 	goto theend;
23933     }
23934     if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range)))
23935     {
23936 	/*
23937 	 * Report an invalid expression in braces, unless the expression
23938 	 * evaluation has been cancelled due to an aborting error, an
23939 	 * interrupt, or an exception.
23940 	 */
23941 	if (!aborting())
23942 	{
23943 	    if (end != NULL)
23944 		EMSG2(_(e_invarg2), start);
23945 	}
23946 	else
23947 	    *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR);
23948 	goto theend;
23949     }
23950 
23951     if (lv.ll_tv != NULL)
23952     {
23953 	if (fdp != NULL)
23954 	{
23955 	    fdp->fd_dict = lv.ll_dict;
23956 	    fdp->fd_newkey = lv.ll_newkey;
23957 	    lv.ll_newkey = NULL;
23958 	    fdp->fd_di = lv.ll_di;
23959 	}
23960 	if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL)
23961 	{
23962 	    name = vim_strsave(lv.ll_tv->vval.v_string);
23963 	    *pp = end;
23964 	}
23965 	else if (lv.ll_tv->v_type == VAR_PARTIAL
23966 					  && lv.ll_tv->vval.v_partial != NULL)
23967 	{
23968 	    name = vim_strsave(lv.ll_tv->vval.v_partial->pt_name);
23969 	    *pp = end;
23970 	    if (partial != NULL)
23971 		*partial = lv.ll_tv->vval.v_partial;
23972 	}
23973 	else
23974 	{
23975 	    if (!skip && !(flags & TFN_QUIET) && (fdp == NULL
23976 			     || lv.ll_dict == NULL || fdp->fd_newkey == NULL))
23977 		EMSG(_(e_funcref));
23978 	    else
23979 		*pp = end;
23980 	    name = NULL;
23981 	}
23982 	goto theend;
23983     }
23984 
23985     if (lv.ll_name == NULL)
23986     {
23987 	/* Error found, but continue after the function name. */
23988 	*pp = end;
23989 	goto theend;
23990     }
23991 
23992     /* Check if the name is a Funcref.  If so, use the value. */
23993     if (lv.ll_exp_name != NULL)
23994     {
23995 	len = (int)STRLEN(lv.ll_exp_name);
23996 	name = deref_func_name(lv.ll_exp_name, &len, partial,
23997 						     flags & TFN_NO_AUTOLOAD);
23998 	if (name == lv.ll_exp_name)
23999 	    name = NULL;
24000     }
24001     else
24002     {
24003 	len = (int)(end - *pp);
24004 	name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD);
24005 	if (name == *pp)
24006 	    name = NULL;
24007     }
24008     if (name != NULL)
24009     {
24010 	name = vim_strsave(name);
24011 	*pp = end;
24012 	if (STRNCMP(name, "<SNR>", 5) == 0)
24013 	{
24014 	    /* Change "<SNR>" to the byte sequence. */
24015 	    name[0] = K_SPECIAL;
24016 	    name[1] = KS_EXTRA;
24017 	    name[2] = (int)KE_SNR;
24018 	    mch_memmove(name + 3, name + 5, STRLEN(name + 5) + 1);
24019 	}
24020 	goto theend;
24021     }
24022 
24023     if (lv.ll_exp_name != NULL)
24024     {
24025 	len = (int)STRLEN(lv.ll_exp_name);
24026 	if (lead <= 2 && lv.ll_name == lv.ll_exp_name
24027 					 && STRNCMP(lv.ll_name, "s:", 2) == 0)
24028 	{
24029 	    /* When there was "s:" already or the name expanded to get a
24030 	     * leading "s:" then remove it. */
24031 	    lv.ll_name += 2;
24032 	    len -= 2;
24033 	    lead = 2;
24034 	}
24035     }
24036     else
24037     {
24038 	/* skip over "s:" and "g:" */
24039 	if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':'))
24040 	    lv.ll_name += 2;
24041 	len = (int)(end - lv.ll_name);
24042     }
24043 
24044     /*
24045      * Copy the function name to allocated memory.
24046      * Accept <SID>name() inside a script, translate into <SNR>123_name().
24047      * Accept <SNR>123_name() outside a script.
24048      */
24049     if (skip)
24050 	lead = 0;	/* do nothing */
24051     else if (lead > 0)
24052     {
24053 	lead = 3;
24054 	if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name))
24055 						       || eval_fname_sid(*pp))
24056 	{
24057 	    /* It's "s:" or "<SID>" */
24058 	    if (current_SID <= 0)
24059 	    {
24060 		EMSG(_(e_usingsid));
24061 		goto theend;
24062 	    }
24063 	    sprintf((char *)sid_buf, "%ld_", (long)current_SID);
24064 	    lead += (int)STRLEN(sid_buf);
24065 	}
24066     }
24067     else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len))
24068     {
24069 	EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"),
24070 								       start);
24071 	goto theend;
24072     }
24073     if (!skip && !(flags & TFN_QUIET))
24074     {
24075 	char_u *cp = vim_strchr(lv.ll_name, ':');
24076 
24077 	if (cp != NULL && cp < end)
24078 	{
24079 	    EMSG2(_("E884: Function name cannot contain a colon: %s"), start);
24080 	    goto theend;
24081 	}
24082     }
24083 
24084     name = alloc((unsigned)(len + lead + 1));
24085     if (name != NULL)
24086     {
24087 	if (lead > 0)
24088 	{
24089 	    name[0] = K_SPECIAL;
24090 	    name[1] = KS_EXTRA;
24091 	    name[2] = (int)KE_SNR;
24092 	    if (lead > 3)	/* If it's "<SID>" */
24093 		STRCPY(name + 3, sid_buf);
24094 	}
24095 	mch_memmove(name + lead, lv.ll_name, (size_t)len);
24096 	name[lead + len] = NUL;
24097     }
24098     *pp = end;
24099 
24100 theend:
24101     clear_lval(&lv);
24102     return name;
24103 }
24104 
24105 /*
24106  * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
24107  * Return 2 if "p" starts with "s:".
24108  * Return 0 otherwise.
24109  */
24110     static int
24111 eval_fname_script(char_u *p)
24112 {
24113     /* Use MB_STRICMP() because in Turkish comparing the "I" may not work with
24114      * the standard library function. */
24115     if (p[0] == '<' && (MB_STRNICMP(p + 1, "SID>", 4) == 0
24116 				       || MB_STRNICMP(p + 1, "SNR>", 4) == 0))
24117 	return 5;
24118     if (p[0] == 's' && p[1] == ':')
24119 	return 2;
24120     return 0;
24121 }
24122 
24123 /*
24124  * Return TRUE if "p" starts with "<SID>" or "s:".
24125  * Only works if eval_fname_script() returned non-zero for "p"!
24126  */
24127     static int
24128 eval_fname_sid(char_u *p)
24129 {
24130     return (*p == 's' || TOUPPER_ASC(p[2]) == 'I');
24131 }
24132 
24133 /*
24134  * List the head of the function: "name(arg1, arg2)".
24135  */
24136     static void
24137 list_func_head(ufunc_T *fp, int indent)
24138 {
24139     int		j;
24140 
24141     msg_start();
24142     if (indent)
24143 	MSG_PUTS("   ");
24144     MSG_PUTS("function ");
24145     if (fp->uf_name[0] == K_SPECIAL)
24146     {
24147 	MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
24148 	msg_puts(fp->uf_name + 3);
24149     }
24150     else
24151 	msg_puts(fp->uf_name);
24152     msg_putchar('(');
24153     for (j = 0; j < fp->uf_args.ga_len; ++j)
24154     {
24155 	if (j)
24156 	    MSG_PUTS(", ");
24157 	msg_puts(FUNCARG(fp, j));
24158     }
24159     if (fp->uf_varargs)
24160     {
24161 	if (j)
24162 	    MSG_PUTS(", ");
24163 	MSG_PUTS("...");
24164     }
24165     msg_putchar(')');
24166     if (fp->uf_flags & FC_ABORT)
24167 	MSG_PUTS(" abort");
24168     if (fp->uf_flags & FC_RANGE)
24169 	MSG_PUTS(" range");
24170     if (fp->uf_flags & FC_DICT)
24171 	MSG_PUTS(" dict");
24172     msg_clr_eos();
24173     if (p_verbose > 0)
24174 	last_set_msg(fp->uf_script_ID);
24175 }
24176 
24177 /*
24178  * Find a function by name, return pointer to it in ufuncs.
24179  * Return NULL for unknown function.
24180  */
24181     static ufunc_T *
24182 find_func(char_u *name)
24183 {
24184     hashitem_T	*hi;
24185 
24186     hi = hash_find(&func_hashtab, name);
24187     if (!HASHITEM_EMPTY(hi))
24188 	return HI2UF(hi);
24189     return NULL;
24190 }
24191 
24192 #if defined(EXITFREE) || defined(PROTO)
24193     void
24194 free_all_functions(void)
24195 {
24196     hashitem_T	*hi;
24197 
24198     /* Need to start all over every time, because func_free() may change the
24199      * hash table. */
24200     while (func_hashtab.ht_used > 0)
24201 	for (hi = func_hashtab.ht_array; ; ++hi)
24202 	    if (!HASHITEM_EMPTY(hi))
24203 	    {
24204 		func_free(HI2UF(hi));
24205 		break;
24206 	    }
24207 }
24208 #endif
24209 
24210     int
24211 translated_function_exists(char_u *name)
24212 {
24213     if (builtin_function(name, -1))
24214 	return find_internal_func(name) >= 0;
24215     return find_func(name) != NULL;
24216 }
24217 
24218 /*
24219  * Return TRUE if a function "name" exists.
24220  */
24221     static int
24222 function_exists(char_u *name)
24223 {
24224     char_u  *nm = name;
24225     char_u  *p;
24226     int	    n = FALSE;
24227 
24228     p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
24229 			    NULL, NULL);
24230     nm = skipwhite(nm);
24231 
24232     /* Only accept "funcname", "funcname ", "funcname (..." and
24233      * "funcname(...", not "funcname!...". */
24234     if (p != NULL && (*nm == NUL || *nm == '('))
24235 	n = translated_function_exists(p);
24236     vim_free(p);
24237     return n;
24238 }
24239 
24240     char_u *
24241 get_expanded_name(char_u *name, int check)
24242 {
24243     char_u	*nm = name;
24244     char_u	*p;
24245 
24246     p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL, NULL);
24247 
24248     if (p != NULL && *nm == NUL)
24249 	if (!check || translated_function_exists(p))
24250 	    return p;
24251 
24252     vim_free(p);
24253     return NULL;
24254 }
24255 
24256 /*
24257  * Return TRUE if "name" looks like a builtin function name: starts with a
24258  * lower case letter and doesn't contain AUTOLOAD_CHAR.
24259  * "len" is the length of "name", or -1 for NUL terminated.
24260  */
24261     static int
24262 builtin_function(char_u *name, int len)
24263 {
24264     char_u *p;
24265 
24266     if (!ASCII_ISLOWER(name[0]))
24267 	return FALSE;
24268     p = vim_strchr(name, AUTOLOAD_CHAR);
24269     return p == NULL || (len > 0 && p > name + len);
24270 }
24271 
24272 #if defined(FEAT_PROFILE) || defined(PROTO)
24273 /*
24274  * Start profiling function "fp".
24275  */
24276     static void
24277 func_do_profile(ufunc_T *fp)
24278 {
24279     int		len = fp->uf_lines.ga_len;
24280 
24281     if (len == 0)
24282 	len = 1;  /* avoid getting error for allocating zero bytes */
24283     fp->uf_tm_count = 0;
24284     profile_zero(&fp->uf_tm_self);
24285     profile_zero(&fp->uf_tm_total);
24286     if (fp->uf_tml_count == NULL)
24287 	fp->uf_tml_count = (int *)alloc_clear((unsigned) (sizeof(int) * len));
24288     if (fp->uf_tml_total == NULL)
24289 	fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned)
24290 						  (sizeof(proftime_T) * len));
24291     if (fp->uf_tml_self == NULL)
24292 	fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned)
24293 						  (sizeof(proftime_T) * len));
24294     fp->uf_tml_idx = -1;
24295     if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL
24296 						   || fp->uf_tml_self == NULL)
24297 	return;	    /* out of memory */
24298 
24299     fp->uf_profiling = TRUE;
24300 }
24301 
24302 /*
24303  * Dump the profiling results for all functions in file "fd".
24304  */
24305     void
24306 func_dump_profile(FILE *fd)
24307 {
24308     hashitem_T	*hi;
24309     int		todo;
24310     ufunc_T	*fp;
24311     int		i;
24312     ufunc_T	**sorttab;
24313     int		st_len = 0;
24314 
24315     todo = (int)func_hashtab.ht_used;
24316     if (todo == 0)
24317 	return;     /* nothing to dump */
24318 
24319     sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T *) * todo));
24320 
24321     for (hi = func_hashtab.ht_array; todo > 0; ++hi)
24322     {
24323 	if (!HASHITEM_EMPTY(hi))
24324 	{
24325 	    --todo;
24326 	    fp = HI2UF(hi);
24327 	    if (fp->uf_profiling)
24328 	    {
24329 		if (sorttab != NULL)
24330 		    sorttab[st_len++] = fp;
24331 
24332 		if (fp->uf_name[0] == K_SPECIAL)
24333 		    fprintf(fd, "FUNCTION  <SNR>%s()\n", fp->uf_name + 3);
24334 		else
24335 		    fprintf(fd, "FUNCTION  %s()\n", fp->uf_name);
24336 		if (fp->uf_tm_count == 1)
24337 		    fprintf(fd, "Called 1 time\n");
24338 		else
24339 		    fprintf(fd, "Called %d times\n", fp->uf_tm_count);
24340 		fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total));
24341 		fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self));
24342 		fprintf(fd, "\n");
24343 		fprintf(fd, "count  total (s)   self (s)\n");
24344 
24345 		for (i = 0; i < fp->uf_lines.ga_len; ++i)
24346 		{
24347 		    if (FUNCLINE(fp, i) == NULL)
24348 			continue;
24349 		    prof_func_line(fd, fp->uf_tml_count[i],
24350 			     &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE);
24351 		    fprintf(fd, "%s\n", FUNCLINE(fp, i));
24352 		}
24353 		fprintf(fd, "\n");
24354 	    }
24355 	}
24356     }
24357 
24358     if (sorttab != NULL && st_len > 0)
24359     {
24360 	qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
24361 							      prof_total_cmp);
24362 	prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE);
24363 	qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
24364 							      prof_self_cmp);
24365 	prof_sort_list(fd, sorttab, st_len, "SELF", TRUE);
24366     }
24367 
24368     vim_free(sorttab);
24369 }
24370 
24371     static void
24372 prof_sort_list(
24373     FILE	*fd,
24374     ufunc_T	**sorttab,
24375     int		st_len,
24376     char	*title,
24377     int		prefer_self)	/* when equal print only self time */
24378 {
24379     int		i;
24380     ufunc_T	*fp;
24381 
24382     fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title);
24383     fprintf(fd, "count  total (s)   self (s)  function\n");
24384     for (i = 0; i < 20 && i < st_len; ++i)
24385     {
24386 	fp = sorttab[i];
24387 	prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self,
24388 								 prefer_self);
24389 	if (fp->uf_name[0] == K_SPECIAL)
24390 	    fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3);
24391 	else
24392 	    fprintf(fd, " %s()\n", fp->uf_name);
24393     }
24394     fprintf(fd, "\n");
24395 }
24396 
24397 /*
24398  * Print the count and times for one function or function line.
24399  */
24400     static void
24401 prof_func_line(
24402     FILE	*fd,
24403     int		count,
24404     proftime_T	*total,
24405     proftime_T	*self,
24406     int		prefer_self)	/* when equal print only self time */
24407 {
24408     if (count > 0)
24409     {
24410 	fprintf(fd, "%5d ", count);
24411 	if (prefer_self && profile_equal(total, self))
24412 	    fprintf(fd, "           ");
24413 	else
24414 	    fprintf(fd, "%s ", profile_msg(total));
24415 	if (!prefer_self && profile_equal(total, self))
24416 	    fprintf(fd, "           ");
24417 	else
24418 	    fprintf(fd, "%s ", profile_msg(self));
24419     }
24420     else
24421 	fprintf(fd, "                            ");
24422 }
24423 
24424 /*
24425  * Compare function for total time sorting.
24426  */
24427     static int
24428 #ifdef __BORLANDC__
24429 _RTLENTRYF
24430 #endif
24431 prof_total_cmp(const void *s1, const void *s2)
24432 {
24433     ufunc_T	*p1, *p2;
24434 
24435     p1 = *(ufunc_T **)s1;
24436     p2 = *(ufunc_T **)s2;
24437     return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total);
24438 }
24439 
24440 /*
24441  * Compare function for self time sorting.
24442  */
24443     static int
24444 #ifdef __BORLANDC__
24445 _RTLENTRYF
24446 #endif
24447 prof_self_cmp(const void *s1, const void *s2)
24448 {
24449     ufunc_T	*p1, *p2;
24450 
24451     p1 = *(ufunc_T **)s1;
24452     p2 = *(ufunc_T **)s2;
24453     return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self);
24454 }
24455 
24456 #endif
24457 
24458 /*
24459  * If "name" has a package name try autoloading the script for it.
24460  * Return TRUE if a package was loaded.
24461  */
24462     static int
24463 script_autoload(
24464     char_u	*name,
24465     int		reload)	    /* load script again when already loaded */
24466 {
24467     char_u	*p;
24468     char_u	*scriptname, *tofree;
24469     int		ret = FALSE;
24470     int		i;
24471 
24472     /* If there is no '#' after name[0] there is no package name. */
24473     p = vim_strchr(name, AUTOLOAD_CHAR);
24474     if (p == NULL || p == name)
24475 	return FALSE;
24476 
24477     tofree = scriptname = autoload_name(name);
24478 
24479     /* Find the name in the list of previously loaded package names.  Skip
24480      * "autoload/", it's always the same. */
24481     for (i = 0; i < ga_loaded.ga_len; ++i)
24482 	if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
24483 	    break;
24484     if (!reload && i < ga_loaded.ga_len)
24485 	ret = FALSE;	    /* was loaded already */
24486     else
24487     {
24488 	/* Remember the name if it wasn't loaded already. */
24489 	if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK)
24490 	{
24491 	    ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname;
24492 	    tofree = NULL;
24493 	}
24494 
24495 	/* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
24496 	if (source_runtime(scriptname, 0) == OK)
24497 	    ret = TRUE;
24498     }
24499 
24500     vim_free(tofree);
24501     return ret;
24502 }
24503 
24504 /*
24505  * Return the autoload script name for a function or variable name.
24506  * Returns NULL when out of memory.
24507  */
24508     static char_u *
24509 autoload_name(char_u *name)
24510 {
24511     char_u	*p;
24512     char_u	*scriptname;
24513 
24514     /* Get the script file name: replace '#' with '/', append ".vim". */
24515     scriptname = alloc((unsigned)(STRLEN(name) + 14));
24516     if (scriptname == NULL)
24517 	return FALSE;
24518     STRCPY(scriptname, "autoload/");
24519     STRCAT(scriptname, name);
24520     *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL;
24521     STRCAT(scriptname, ".vim");
24522     while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL)
24523 	*p = '/';
24524     return scriptname;
24525 }
24526 
24527 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
24528 
24529 /*
24530  * Function given to ExpandGeneric() to obtain the list of user defined
24531  * function names.
24532  */
24533     char_u *
24534 get_user_func_name(expand_T *xp, int idx)
24535 {
24536     static long_u	done;
24537     static hashitem_T	*hi;
24538     ufunc_T		*fp;
24539 
24540     if (idx == 0)
24541     {
24542 	done = 0;
24543 	hi = func_hashtab.ht_array;
24544     }
24545     if (done < func_hashtab.ht_used)
24546     {
24547 	if (done++ > 0)
24548 	    ++hi;
24549 	while (HASHITEM_EMPTY(hi))
24550 	    ++hi;
24551 	fp = HI2UF(hi);
24552 
24553 	if (fp->uf_flags & FC_DICT)
24554 	    return (char_u *)""; /* don't show dict functions */
24555 
24556 	if (STRLEN(fp->uf_name) + 4 >= IOSIZE)
24557 	    return fp->uf_name;	/* prevents overflow */
24558 
24559 	cat_func_name(IObuff, fp);
24560 	if (xp->xp_context != EXPAND_USER_FUNC)
24561 	{
24562 	    STRCAT(IObuff, "(");
24563 	    if (!fp->uf_varargs && fp->uf_args.ga_len == 0)
24564 		STRCAT(IObuff, ")");
24565 	}
24566 	return IObuff;
24567     }
24568     return NULL;
24569 }
24570 
24571 #endif /* FEAT_CMDL_COMPL */
24572 
24573 /*
24574  * Copy the function name of "fp" to buffer "buf".
24575  * "buf" must be able to hold the function name plus three bytes.
24576  * Takes care of script-local function names.
24577  */
24578     static void
24579 cat_func_name(char_u *buf, ufunc_T *fp)
24580 {
24581     if (fp->uf_name[0] == K_SPECIAL)
24582     {
24583 	STRCPY(buf, "<SNR>");
24584 	STRCAT(buf, fp->uf_name + 3);
24585     }
24586     else
24587 	STRCPY(buf, fp->uf_name);
24588 }
24589 
24590 /*
24591  * ":delfunction {name}"
24592  */
24593     void
24594 ex_delfunction(exarg_T *eap)
24595 {
24596     ufunc_T	*fp = NULL;
24597     char_u	*p;
24598     char_u	*name;
24599     funcdict_T	fudi;
24600 
24601     p = eap->arg;
24602     name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
24603     vim_free(fudi.fd_newkey);
24604     if (name == NULL)
24605     {
24606 	if (fudi.fd_dict != NULL && !eap->skip)
24607 	    EMSG(_(e_funcref));
24608 	return;
24609     }
24610     if (!ends_excmd(*skipwhite(p)))
24611     {
24612 	vim_free(name);
24613 	EMSG(_(e_trailing));
24614 	return;
24615     }
24616     eap->nextcmd = check_nextcmd(p);
24617     if (eap->nextcmd != NULL)
24618 	*p = NUL;
24619 
24620     if (!eap->skip)
24621 	fp = find_func(name);
24622     vim_free(name);
24623 
24624     if (!eap->skip)
24625     {
24626 	if (fp == NULL)
24627 	{
24628 	    EMSG2(_(e_nofunc), eap->arg);
24629 	    return;
24630 	}
24631 	if (fp->uf_calls > 0)
24632 	{
24633 	    EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg);
24634 	    return;
24635 	}
24636 
24637 	if (fudi.fd_dict != NULL)
24638 	{
24639 	    /* Delete the dict item that refers to the function, it will
24640 	     * invoke func_unref() and possibly delete the function. */
24641 	    dictitem_remove(fudi.fd_dict, fudi.fd_di);
24642 	}
24643 	else
24644 	    func_free(fp);
24645     }
24646 }
24647 
24648 /*
24649  * Free a function and remove it from the list of functions.
24650  */
24651     static void
24652 func_free(ufunc_T *fp)
24653 {
24654     hashitem_T	*hi;
24655 
24656     /* clear this function */
24657     ga_clear_strings(&(fp->uf_args));
24658     ga_clear_strings(&(fp->uf_lines));
24659 #ifdef FEAT_PROFILE
24660     vim_free(fp->uf_tml_count);
24661     vim_free(fp->uf_tml_total);
24662     vim_free(fp->uf_tml_self);
24663 #endif
24664 
24665     /* remove the function from the function hashtable */
24666     hi = hash_find(&func_hashtab, UF2HIKEY(fp));
24667     if (HASHITEM_EMPTY(hi))
24668 	EMSG2(_(e_intern2), "func_free()");
24669     else
24670 	hash_remove(&func_hashtab, hi);
24671 
24672     vim_free(fp);
24673 }
24674 
24675 /*
24676  * Unreference a Function: decrement the reference count and free it when it
24677  * becomes zero.  Only for numbered functions.
24678  */
24679     void
24680 func_unref(char_u *name)
24681 {
24682     ufunc_T *fp;
24683 
24684     if (name != NULL && isdigit(*name))
24685     {
24686 	fp = find_func(name);
24687 	if (fp == NULL)
24688 	    EMSG2(_(e_intern2), "func_unref()");
24689 	else if (--fp->uf_refcount <= 0)
24690 	{
24691 	    /* Only delete it when it's not being used.  Otherwise it's done
24692 	     * when "uf_calls" becomes zero. */
24693 	    if (fp->uf_calls == 0)
24694 		func_free(fp);
24695 	}
24696     }
24697 }
24698 
24699 /*
24700  * Count a reference to a Function.
24701  */
24702     void
24703 func_ref(char_u *name)
24704 {
24705     ufunc_T *fp;
24706 
24707     if (name != NULL && isdigit(*name))
24708     {
24709 	fp = find_func(name);
24710 	if (fp == NULL)
24711 	    EMSG2(_(e_intern2), "func_ref()");
24712 	else
24713 	    ++fp->uf_refcount;
24714     }
24715 }
24716 
24717 /*
24718  * Call a user function.
24719  */
24720     static void
24721 call_user_func(
24722     ufunc_T	*fp,		/* pointer to function */
24723     int		argcount,	/* nr of args */
24724     typval_T	*argvars,	/* arguments */
24725     typval_T	*rettv,		/* return value */
24726     linenr_T	firstline,	/* first line of range */
24727     linenr_T	lastline,	/* last line of range */
24728     dict_T	*selfdict)	/* Dictionary for "self" */
24729 {
24730     char_u	*save_sourcing_name;
24731     linenr_T	save_sourcing_lnum;
24732     scid_T	save_current_SID;
24733     funccall_T	*fc;
24734     int		save_did_emsg;
24735     static int	depth = 0;
24736     dictitem_T	*v;
24737     int		fixvar_idx = 0;	/* index in fixvar[] */
24738     int		i;
24739     int		ai;
24740     char_u	numbuf[NUMBUFLEN];
24741     char_u	*name;
24742     size_t	len;
24743 #ifdef FEAT_PROFILE
24744     proftime_T	wait_start;
24745     proftime_T	call_start;
24746 #endif
24747 
24748     /* If depth of calling is getting too high, don't execute the function */
24749     if (depth >= p_mfd)
24750     {
24751 	EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'"));
24752 	rettv->v_type = VAR_NUMBER;
24753 	rettv->vval.v_number = -1;
24754 	return;
24755     }
24756     ++depth;
24757 
24758     line_breakcheck();		/* check for CTRL-C hit */
24759 
24760     fc = (funccall_T *)alloc(sizeof(funccall_T));
24761     fc->caller = current_funccal;
24762     current_funccal = fc;
24763     fc->func = fp;
24764     fc->rettv = rettv;
24765     rettv->vval.v_number = 0;
24766     fc->linenr = 0;
24767     fc->returned = FALSE;
24768     fc->level = ex_nesting_level;
24769     /* Check if this function has a breakpoint. */
24770     fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
24771     fc->dbg_tick = debug_tick;
24772 
24773     /*
24774      * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
24775      * with names up to VAR_SHORT_LEN long.  This avoids having to alloc/free
24776      * each argument variable and saves a lot of time.
24777      */
24778     /*
24779      * Init l: variables.
24780      */
24781     init_var_dict(&fc->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE);
24782     if (selfdict != NULL)
24783     {
24784 	/* Set l:self to "selfdict".  Use "name" to avoid a warning from
24785 	 * some compiler that checks the destination size. */
24786 	v = &fc->fixvar[fixvar_idx++].var;
24787 	name = v->di_key;
24788 	STRCPY(name, "self");
24789 	v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX;
24790 	hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v));
24791 	v->di_tv.v_type = VAR_DICT;
24792 	v->di_tv.v_lock = 0;
24793 	v->di_tv.vval.v_dict = selfdict;
24794 	++selfdict->dv_refcount;
24795     }
24796 
24797     /*
24798      * Init a: variables.
24799      * Set a:0 to "argcount".
24800      * Set a:000 to a list with room for the "..." arguments.
24801      */
24802     init_var_dict(&fc->l_avars, &fc->l_avars_var, VAR_SCOPE);
24803     add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0",
24804 				(varnumber_T)(argcount - fp->uf_args.ga_len));
24805     /* Use "name" to avoid a warning from some compiler that checks the
24806      * destination size. */
24807     v = &fc->fixvar[fixvar_idx++].var;
24808     name = v->di_key;
24809     STRCPY(name, "000");
24810     v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
24811     hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
24812     v->di_tv.v_type = VAR_LIST;
24813     v->di_tv.v_lock = VAR_FIXED;
24814     v->di_tv.vval.v_list = &fc->l_varlist;
24815     vim_memset(&fc->l_varlist, 0, sizeof(list_T));
24816     fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT;
24817     fc->l_varlist.lv_lock = VAR_FIXED;
24818 
24819     /*
24820      * Set a:firstline to "firstline" and a:lastline to "lastline".
24821      * Set a:name to named arguments.
24822      * Set a:N to the "..." arguments.
24823      */
24824     add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline",
24825 						      (varnumber_T)firstline);
24826     add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline",
24827 						       (varnumber_T)lastline);
24828     for (i = 0; i < argcount; ++i)
24829     {
24830 	ai = i - fp->uf_args.ga_len;
24831 	if (ai < 0)
24832 	    /* named argument a:name */
24833 	    name = FUNCARG(fp, i);
24834 	else
24835 	{
24836 	    /* "..." argument a:1, a:2, etc. */
24837 	    sprintf((char *)numbuf, "%d", ai + 1);
24838 	    name = numbuf;
24839 	}
24840 	if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN)
24841 	{
24842 	    v = &fc->fixvar[fixvar_idx++].var;
24843 	    v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
24844 	}
24845 	else
24846 	{
24847 	    v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
24848 							     + STRLEN(name)));
24849 	    if (v == NULL)
24850 		break;
24851 	    v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX | DI_FLAGS_ALLOC;
24852 	}
24853 	STRCPY(v->di_key, name);
24854 	hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
24855 
24856 	/* Note: the values are copied directly to avoid alloc/free.
24857 	 * "argvars" must have VAR_FIXED for v_lock. */
24858 	v->di_tv = argvars[i];
24859 	v->di_tv.v_lock = VAR_FIXED;
24860 
24861 	if (ai >= 0 && ai < MAX_FUNC_ARGS)
24862 	{
24863 	    list_append(&fc->l_varlist, &fc->l_listitems[ai]);
24864 	    fc->l_listitems[ai].li_tv = argvars[i];
24865 	    fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED;
24866 	}
24867     }
24868 
24869     /* Don't redraw while executing the function. */
24870     ++RedrawingDisabled;
24871     save_sourcing_name = sourcing_name;
24872     save_sourcing_lnum = sourcing_lnum;
24873     sourcing_lnum = 1;
24874     /* need space for function name + ("function " + 3) or "[number]" */
24875     len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name))
24876 						   + STRLEN(fp->uf_name) + 20;
24877     sourcing_name = alloc((unsigned)len);
24878     if (sourcing_name != NULL)
24879     {
24880 	if (save_sourcing_name != NULL
24881 			  && STRNCMP(save_sourcing_name, "function ", 9) == 0)
24882 	    sprintf((char *)sourcing_name, "%s[%d]..",
24883 				 save_sourcing_name, (int)save_sourcing_lnum);
24884 	else
24885 	    STRCPY(sourcing_name, "function ");
24886 	cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
24887 
24888 	if (p_verbose >= 12)
24889 	{
24890 	    ++no_wait_return;
24891 	    verbose_enter_scroll();
24892 
24893 	    smsg((char_u *)_("calling %s"), sourcing_name);
24894 	    if (p_verbose >= 14)
24895 	    {
24896 		char_u	buf[MSG_BUF_LEN];
24897 		char_u	numbuf2[NUMBUFLEN];
24898 		char_u	*tofree;
24899 		char_u	*s;
24900 
24901 		msg_puts((char_u *)"(");
24902 		for (i = 0; i < argcount; ++i)
24903 		{
24904 		    if (i > 0)
24905 			msg_puts((char_u *)", ");
24906 		    if (argvars[i].v_type == VAR_NUMBER)
24907 			msg_outnum((long)argvars[i].vval.v_number);
24908 		    else
24909 		    {
24910 			/* Do not want errors such as E724 here. */
24911 			++emsg_off;
24912 			s = tv2string(&argvars[i], &tofree, numbuf2, 0);
24913 			--emsg_off;
24914 			if (s != NULL)
24915 			{
24916 			    if (vim_strsize(s) > MSG_BUF_CLEN)
24917 			    {
24918 				trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
24919 				s = buf;
24920 			    }
24921 			    msg_puts(s);
24922 			    vim_free(tofree);
24923 			}
24924 		    }
24925 		}
24926 		msg_puts((char_u *)")");
24927 	    }
24928 	    msg_puts((char_u *)"\n");   /* don't overwrite this either */
24929 
24930 	    verbose_leave_scroll();
24931 	    --no_wait_return;
24932 	}
24933     }
24934 #ifdef FEAT_PROFILE
24935     if (do_profiling == PROF_YES)
24936     {
24937 	if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL))
24938 	    func_do_profile(fp);
24939 	if (fp->uf_profiling
24940 		    || (fc->caller != NULL && fc->caller->func->uf_profiling))
24941 	{
24942 	    ++fp->uf_tm_count;
24943 	    profile_start(&call_start);
24944 	    profile_zero(&fp->uf_tm_children);
24945 	}
24946 	script_prof_save(&wait_start);
24947     }
24948 #endif
24949 
24950     save_current_SID = current_SID;
24951     current_SID = fp->uf_script_ID;
24952     save_did_emsg = did_emsg;
24953     did_emsg = FALSE;
24954 
24955     /* call do_cmdline() to execute the lines */
24956     do_cmdline(NULL, get_func_line, (void *)fc,
24957 				     DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
24958 
24959     --RedrawingDisabled;
24960 
24961     /* when the function was aborted because of an error, return -1 */
24962     if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN)
24963     {
24964 	clear_tv(rettv);
24965 	rettv->v_type = VAR_NUMBER;
24966 	rettv->vval.v_number = -1;
24967     }
24968 
24969 #ifdef FEAT_PROFILE
24970     if (do_profiling == PROF_YES && (fp->uf_profiling
24971 		    || (fc->caller != NULL && fc->caller->func->uf_profiling)))
24972     {
24973 	profile_end(&call_start);
24974 	profile_sub_wait(&wait_start, &call_start);
24975 	profile_add(&fp->uf_tm_total, &call_start);
24976 	profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children);
24977 	if (fc->caller != NULL && fc->caller->func->uf_profiling)
24978 	{
24979 	    profile_add(&fc->caller->func->uf_tm_children, &call_start);
24980 	    profile_add(&fc->caller->func->uf_tml_children, &call_start);
24981 	}
24982     }
24983 #endif
24984 
24985     /* when being verbose, mention the return value */
24986     if (p_verbose >= 12)
24987     {
24988 	++no_wait_return;
24989 	verbose_enter_scroll();
24990 
24991 	if (aborting())
24992 	    smsg((char_u *)_("%s aborted"), sourcing_name);
24993 	else if (fc->rettv->v_type == VAR_NUMBER)
24994 	    smsg((char_u *)_("%s returning #%ld"), sourcing_name,
24995 					       (long)fc->rettv->vval.v_number);
24996 	else
24997 	{
24998 	    char_u	buf[MSG_BUF_LEN];
24999 	    char_u	numbuf2[NUMBUFLEN];
25000 	    char_u	*tofree;
25001 	    char_u	*s;
25002 
25003 	    /* The value may be very long.  Skip the middle part, so that we
25004 	     * have some idea how it starts and ends. smsg() would always
25005 	     * truncate it at the end. Don't want errors such as E724 here. */
25006 	    ++emsg_off;
25007 	    s = tv2string(fc->rettv, &tofree, numbuf2, 0);
25008 	    --emsg_off;
25009 	    if (s != NULL)
25010 	    {
25011 		if (vim_strsize(s) > MSG_BUF_CLEN)
25012 		{
25013 		    trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
25014 		    s = buf;
25015 		}
25016 		smsg((char_u *)_("%s returning %s"), sourcing_name, s);
25017 		vim_free(tofree);
25018 	    }
25019 	}
25020 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
25021 
25022 	verbose_leave_scroll();
25023 	--no_wait_return;
25024     }
25025 
25026     vim_free(sourcing_name);
25027     sourcing_name = save_sourcing_name;
25028     sourcing_lnum = save_sourcing_lnum;
25029     current_SID = save_current_SID;
25030 #ifdef FEAT_PROFILE
25031     if (do_profiling == PROF_YES)
25032 	script_prof_restore(&wait_start);
25033 #endif
25034 
25035     if (p_verbose >= 12 && sourcing_name != NULL)
25036     {
25037 	++no_wait_return;
25038 	verbose_enter_scroll();
25039 
25040 	smsg((char_u *)_("continuing in %s"), sourcing_name);
25041 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
25042 
25043 	verbose_leave_scroll();
25044 	--no_wait_return;
25045     }
25046 
25047     did_emsg |= save_did_emsg;
25048     current_funccal = fc->caller;
25049     --depth;
25050 
25051     /* If the a:000 list and the l: and a: dicts are not referenced we can
25052      * free the funccall_T and what's in it. */
25053     if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
25054 	    && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
25055 	    && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
25056     {
25057 	free_funccal(fc, FALSE);
25058     }
25059     else
25060     {
25061 	hashitem_T	*hi;
25062 	listitem_T	*li;
25063 	int		todo;
25064 
25065 	/* "fc" is still in use.  This can happen when returning "a:000" or
25066 	 * assigning "l:" to a global variable.
25067 	 * Link "fc" in the list for garbage collection later. */
25068 	fc->caller = previous_funccal;
25069 	previous_funccal = fc;
25070 
25071 	/* Make a copy of the a: variables, since we didn't do that above. */
25072 	todo = (int)fc->l_avars.dv_hashtab.ht_used;
25073 	for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
25074 	{
25075 	    if (!HASHITEM_EMPTY(hi))
25076 	    {
25077 		--todo;
25078 		v = HI2DI(hi);
25079 		copy_tv(&v->di_tv, &v->di_tv);
25080 	    }
25081 	}
25082 
25083 	/* Make a copy of the a:000 items, since we didn't do that above. */
25084 	for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
25085 	    copy_tv(&li->li_tv, &li->li_tv);
25086     }
25087 }
25088 
25089 /*
25090  * Return TRUE if items in "fc" do not have "copyID".  That means they are not
25091  * referenced from anywhere that is in use.
25092  */
25093     static int
25094 can_free_funccal(funccall_T *fc, int copyID)
25095 {
25096     return (fc->l_varlist.lv_copyID != copyID
25097 	    && fc->l_vars.dv_copyID != copyID
25098 	    && fc->l_avars.dv_copyID != copyID);
25099 }
25100 
25101 /*
25102  * Free "fc" and what it contains.
25103  */
25104    static void
25105 free_funccal(
25106     funccall_T	*fc,
25107     int		free_val)  /* a: vars were allocated */
25108 {
25109     listitem_T	*li;
25110 
25111     /* The a: variables typevals may not have been allocated, only free the
25112      * allocated variables. */
25113     vars_clear_ext(&fc->l_avars.dv_hashtab, free_val);
25114 
25115     /* free all l: variables */
25116     vars_clear(&fc->l_vars.dv_hashtab);
25117 
25118     /* Free the a:000 variables if they were allocated. */
25119     if (free_val)
25120 	for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
25121 	    clear_tv(&li->li_tv);
25122 
25123     vim_free(fc);
25124 }
25125 
25126 /*
25127  * Add a number variable "name" to dict "dp" with value "nr".
25128  */
25129     static void
25130 add_nr_var(
25131     dict_T	*dp,
25132     dictitem_T	*v,
25133     char	*name,
25134     varnumber_T nr)
25135 {
25136     STRCPY(v->di_key, name);
25137     v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
25138     hash_add(&dp->dv_hashtab, DI2HIKEY(v));
25139     v->di_tv.v_type = VAR_NUMBER;
25140     v->di_tv.v_lock = VAR_FIXED;
25141     v->di_tv.vval.v_number = nr;
25142 }
25143 
25144 /*
25145  * ":return [expr]"
25146  */
25147     void
25148 ex_return(exarg_T *eap)
25149 {
25150     char_u	*arg = eap->arg;
25151     typval_T	rettv;
25152     int		returning = FALSE;
25153 
25154     if (current_funccal == NULL)
25155     {
25156 	EMSG(_("E133: :return not inside a function"));
25157 	return;
25158     }
25159 
25160     if (eap->skip)
25161 	++emsg_skip;
25162 
25163     eap->nextcmd = NULL;
25164     if ((*arg != NUL && *arg != '|' && *arg != '\n')
25165 	    && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL)
25166     {
25167 	if (!eap->skip)
25168 	    returning = do_return(eap, FALSE, TRUE, &rettv);
25169 	else
25170 	    clear_tv(&rettv);
25171     }
25172     /* It's safer to return also on error. */
25173     else if (!eap->skip)
25174     {
25175 	/*
25176 	 * Return unless the expression evaluation has been cancelled due to an
25177 	 * aborting error, an interrupt, or an exception.
25178 	 */
25179 	if (!aborting())
25180 	    returning = do_return(eap, FALSE, TRUE, NULL);
25181     }
25182 
25183     /* When skipping or the return gets pending, advance to the next command
25184      * in this line (!returning).  Otherwise, ignore the rest of the line.
25185      * Following lines will be ignored by get_func_line(). */
25186     if (returning)
25187 	eap->nextcmd = NULL;
25188     else if (eap->nextcmd == NULL)	    /* no argument */
25189 	eap->nextcmd = check_nextcmd(arg);
25190 
25191     if (eap->skip)
25192 	--emsg_skip;
25193 }
25194 
25195 /*
25196  * Return from a function.  Possibly makes the return pending.  Also called
25197  * for a pending return at the ":endtry" or after returning from an extra
25198  * do_cmdline().  "reanimate" is used in the latter case.  "is_cmd" is set
25199  * when called due to a ":return" command.  "rettv" may point to a typval_T
25200  * with the return rettv.  Returns TRUE when the return can be carried out,
25201  * FALSE when the return gets pending.
25202  */
25203     int
25204 do_return(
25205     exarg_T	*eap,
25206     int		reanimate,
25207     int		is_cmd,
25208     void	*rettv)
25209 {
25210     int		idx;
25211     struct condstack *cstack = eap->cstack;
25212 
25213     if (reanimate)
25214 	/* Undo the return. */
25215 	current_funccal->returned = FALSE;
25216 
25217     /*
25218      * Cleanup (and inactivate) conditionals, but stop when a try conditional
25219      * not in its finally clause (which then is to be executed next) is found.
25220      * In this case, make the ":return" pending for execution at the ":endtry".
25221      * Otherwise, return normally.
25222      */
25223     idx = cleanup_conditionals(eap->cstack, 0, TRUE);
25224     if (idx >= 0)
25225     {
25226 	cstack->cs_pending[idx] = CSTP_RETURN;
25227 
25228 	if (!is_cmd && !reanimate)
25229 	    /* A pending return again gets pending.  "rettv" points to an
25230 	     * allocated variable with the rettv of the original ":return"'s
25231 	     * argument if present or is NULL else. */
25232 	    cstack->cs_rettv[idx] = rettv;
25233 	else
25234 	{
25235 	    /* When undoing a return in order to make it pending, get the stored
25236 	     * return rettv. */
25237 	    if (reanimate)
25238 		rettv = current_funccal->rettv;
25239 
25240 	    if (rettv != NULL)
25241 	    {
25242 		/* Store the value of the pending return. */
25243 		if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL)
25244 		    *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
25245 		else
25246 		    EMSG(_(e_outofmem));
25247 	    }
25248 	    else
25249 		cstack->cs_rettv[idx] = NULL;
25250 
25251 	    if (reanimate)
25252 	    {
25253 		/* The pending return value could be overwritten by a ":return"
25254 		 * without argument in a finally clause; reset the default
25255 		 * return value. */
25256 		current_funccal->rettv->v_type = VAR_NUMBER;
25257 		current_funccal->rettv->vval.v_number = 0;
25258 	    }
25259 	}
25260 	report_make_pending(CSTP_RETURN, rettv);
25261     }
25262     else
25263     {
25264 	current_funccal->returned = TRUE;
25265 
25266 	/* If the return is carried out now, store the return value.  For
25267 	 * a return immediately after reanimation, the value is already
25268 	 * there. */
25269 	if (!reanimate && rettv != NULL)
25270 	{
25271 	    clear_tv(current_funccal->rettv);
25272 	    *current_funccal->rettv = *(typval_T *)rettv;
25273 	    if (!is_cmd)
25274 		vim_free(rettv);
25275 	}
25276     }
25277 
25278     return idx < 0;
25279 }
25280 
25281 /*
25282  * Free the variable with a pending return value.
25283  */
25284     void
25285 discard_pending_return(void *rettv)
25286 {
25287     free_tv((typval_T *)rettv);
25288 }
25289 
25290 /*
25291  * Generate a return command for producing the value of "rettv".  The result
25292  * is an allocated string.  Used by report_pending() for verbose messages.
25293  */
25294     char_u *
25295 get_return_cmd(void *rettv)
25296 {
25297     char_u	*s = NULL;
25298     char_u	*tofree = NULL;
25299     char_u	numbuf[NUMBUFLEN];
25300 
25301     if (rettv != NULL)
25302 	s = echo_string((typval_T *)rettv, &tofree, numbuf, 0);
25303     if (s == NULL)
25304 	s = (char_u *)"";
25305 
25306     STRCPY(IObuff, ":return ");
25307     STRNCPY(IObuff + 8, s, IOSIZE - 8);
25308     if (STRLEN(s) + 8 >= IOSIZE)
25309 	STRCPY(IObuff + IOSIZE - 4, "...");
25310     vim_free(tofree);
25311     return vim_strsave(IObuff);
25312 }
25313 
25314 /*
25315  * Get next function line.
25316  * Called by do_cmdline() to get the next line.
25317  * Returns allocated string, or NULL for end of function.
25318  */
25319     char_u *
25320 get_func_line(
25321     int	    c UNUSED,
25322     void    *cookie,
25323     int	    indent UNUSED)
25324 {
25325     funccall_T	*fcp = (funccall_T *)cookie;
25326     ufunc_T	*fp = fcp->func;
25327     char_u	*retval;
25328     garray_T	*gap;  /* growarray with function lines */
25329 
25330     /* If breakpoints have been added/deleted need to check for it. */
25331     if (fcp->dbg_tick != debug_tick)
25332     {
25333 	fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
25334 							       sourcing_lnum);
25335 	fcp->dbg_tick = debug_tick;
25336     }
25337 #ifdef FEAT_PROFILE
25338     if (do_profiling == PROF_YES)
25339 	func_line_end(cookie);
25340 #endif
25341 
25342     gap = &fp->uf_lines;
25343     if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
25344 	    || fcp->returned)
25345 	retval = NULL;
25346     else
25347     {
25348 	/* Skip NULL lines (continuation lines). */
25349 	while (fcp->linenr < gap->ga_len
25350 			  && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL)
25351 	    ++fcp->linenr;
25352 	if (fcp->linenr >= gap->ga_len)
25353 	    retval = NULL;
25354 	else
25355 	{
25356 	    retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
25357 	    sourcing_lnum = fcp->linenr;
25358 #ifdef FEAT_PROFILE
25359 	    if (do_profiling == PROF_YES)
25360 		func_line_start(cookie);
25361 #endif
25362 	}
25363     }
25364 
25365     /* Did we encounter a breakpoint? */
25366     if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum)
25367     {
25368 	dbg_breakpoint(fp->uf_name, sourcing_lnum);
25369 	/* Find next breakpoint. */
25370 	fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
25371 							       sourcing_lnum);
25372 	fcp->dbg_tick = debug_tick;
25373     }
25374 
25375     return retval;
25376 }
25377 
25378 #if defined(FEAT_PROFILE) || defined(PROTO)
25379 /*
25380  * Called when starting to read a function line.
25381  * "sourcing_lnum" must be correct!
25382  * When skipping lines it may not actually be executed, but we won't find out
25383  * until later and we need to store the time now.
25384  */
25385     void
25386 func_line_start(void *cookie)
25387 {
25388     funccall_T	*fcp = (funccall_T *)cookie;
25389     ufunc_T	*fp = fcp->func;
25390 
25391     if (fp->uf_profiling && sourcing_lnum >= 1
25392 				      && sourcing_lnum <= fp->uf_lines.ga_len)
25393     {
25394 	fp->uf_tml_idx = sourcing_lnum - 1;
25395 	/* Skip continuation lines. */
25396 	while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
25397 	    --fp->uf_tml_idx;
25398 	fp->uf_tml_execed = FALSE;
25399 	profile_start(&fp->uf_tml_start);
25400 	profile_zero(&fp->uf_tml_children);
25401 	profile_get_wait(&fp->uf_tml_wait);
25402     }
25403 }
25404 
25405 /*
25406  * Called when actually executing a function line.
25407  */
25408     void
25409 func_line_exec(void *cookie)
25410 {
25411     funccall_T	*fcp = (funccall_T *)cookie;
25412     ufunc_T	*fp = fcp->func;
25413 
25414     if (fp->uf_profiling && fp->uf_tml_idx >= 0)
25415 	fp->uf_tml_execed = TRUE;
25416 }
25417 
25418 /*
25419  * Called when done with a function line.
25420  */
25421     void
25422 func_line_end(void *cookie)
25423 {
25424     funccall_T	*fcp = (funccall_T *)cookie;
25425     ufunc_T	*fp = fcp->func;
25426 
25427     if (fp->uf_profiling && fp->uf_tml_idx >= 0)
25428     {
25429 	if (fp->uf_tml_execed)
25430 	{
25431 	    ++fp->uf_tml_count[fp->uf_tml_idx];
25432 	    profile_end(&fp->uf_tml_start);
25433 	    profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start);
25434 	    profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start);
25435 	    profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start,
25436 							&fp->uf_tml_children);
25437 	}
25438 	fp->uf_tml_idx = -1;
25439     }
25440 }
25441 #endif
25442 
25443 /*
25444  * Return TRUE if the currently active function should be ended, because a
25445  * return was encountered or an error occurred.  Used inside a ":while".
25446  */
25447     int
25448 func_has_ended(void *cookie)
25449 {
25450     funccall_T  *fcp = (funccall_T *)cookie;
25451 
25452     /* Ignore the "abort" flag if the abortion behavior has been changed due to
25453      * an error inside a try conditional. */
25454     return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
25455 	    || fcp->returned);
25456 }
25457 
25458 /*
25459  * return TRUE if cookie indicates a function which "abort"s on errors.
25460  */
25461     int
25462 func_has_abort(
25463     void    *cookie)
25464 {
25465     return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT;
25466 }
25467 
25468 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)
25469 typedef enum
25470 {
25471     VAR_FLAVOUR_DEFAULT,	/* doesn't start with uppercase */
25472     VAR_FLAVOUR_SESSION,	/* starts with uppercase, some lower */
25473     VAR_FLAVOUR_VIMINFO		/* all uppercase */
25474 } var_flavour_T;
25475 
25476 static var_flavour_T var_flavour(char_u *varname);
25477 
25478     static var_flavour_T
25479 var_flavour(char_u *varname)
25480 {
25481     char_u *p = varname;
25482 
25483     if (ASCII_ISUPPER(*p))
25484     {
25485 	while (*(++p))
25486 	    if (ASCII_ISLOWER(*p))
25487 		return VAR_FLAVOUR_SESSION;
25488 	return VAR_FLAVOUR_VIMINFO;
25489     }
25490     else
25491 	return VAR_FLAVOUR_DEFAULT;
25492 }
25493 #endif
25494 
25495 #if defined(FEAT_VIMINFO) || defined(PROTO)
25496 /*
25497  * Restore global vars that start with a capital from the viminfo file
25498  */
25499     int
25500 read_viminfo_varlist(vir_T *virp, int writing)
25501 {
25502     char_u	*tab;
25503     int		type = VAR_NUMBER;
25504     typval_T	tv;
25505     funccall_T  *save_funccal;
25506 
25507     if (!writing && (find_viminfo_parameter('!') != NULL))
25508     {
25509 	tab = vim_strchr(virp->vir_line + 1, '\t');
25510 	if (tab != NULL)
25511 	{
25512 	    *tab++ = '\0';	/* isolate the variable name */
25513 	    switch (*tab)
25514 	    {
25515 		case 'S': type = VAR_STRING; break;
25516 #ifdef FEAT_FLOAT
25517 		case 'F': type = VAR_FLOAT; break;
25518 #endif
25519 		case 'D': type = VAR_DICT; break;
25520 		case 'L': type = VAR_LIST; break;
25521 		case 'X': type = VAR_SPECIAL; break;
25522 	    }
25523 
25524 	    tab = vim_strchr(tab, '\t');
25525 	    if (tab != NULL)
25526 	    {
25527 		tv.v_type = type;
25528 		if (type == VAR_STRING || type == VAR_DICT || type == VAR_LIST)
25529 		    tv.vval.v_string = viminfo_readstring(virp,
25530 				       (int)(tab - virp->vir_line + 1), TRUE);
25531 #ifdef FEAT_FLOAT
25532 		else if (type == VAR_FLOAT)
25533 		    (void)string2float(tab + 1, &tv.vval.v_float);
25534 #endif
25535 		else
25536 		    tv.vval.v_number = atol((char *)tab + 1);
25537 		if (type == VAR_DICT || type == VAR_LIST)
25538 		{
25539 		    typval_T *etv = eval_expr(tv.vval.v_string, NULL);
25540 
25541 		    if (etv == NULL)
25542 			/* Failed to parse back the dict or list, use it as a
25543 			 * string. */
25544 			tv.v_type = VAR_STRING;
25545 		    else
25546 		    {
25547 			vim_free(tv.vval.v_string);
25548 			tv = *etv;
25549 			vim_free(etv);
25550 		    }
25551 		}
25552 
25553 		/* when in a function use global variables */
25554 		save_funccal = current_funccal;
25555 		current_funccal = NULL;
25556 		set_var(virp->vir_line + 1, &tv, FALSE);
25557 		current_funccal = save_funccal;
25558 
25559 		if (tv.v_type == VAR_STRING)
25560 		    vim_free(tv.vval.v_string);
25561 		else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST)
25562 		    clear_tv(&tv);
25563 	    }
25564 	}
25565     }
25566 
25567     return viminfo_readline(virp);
25568 }
25569 
25570 /*
25571  * Write global vars that start with a capital to the viminfo file
25572  */
25573     void
25574 write_viminfo_varlist(FILE *fp)
25575 {
25576     hashitem_T	*hi;
25577     dictitem_T	*this_var;
25578     int		todo;
25579     char	*s = "";
25580     char_u	*p;
25581     char_u	*tofree;
25582     char_u	numbuf[NUMBUFLEN];
25583 
25584     if (find_viminfo_parameter('!') == NULL)
25585 	return;
25586 
25587     fputs(_("\n# global variables:\n"), fp);
25588 
25589     todo = (int)globvarht.ht_used;
25590     for (hi = globvarht.ht_array; todo > 0; ++hi)
25591     {
25592 	if (!HASHITEM_EMPTY(hi))
25593 	{
25594 	    --todo;
25595 	    this_var = HI2DI(hi);
25596 	    if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO)
25597 	    {
25598 		switch (this_var->di_tv.v_type)
25599 		{
25600 		    case VAR_STRING: s = "STR"; break;
25601 		    case VAR_NUMBER: s = "NUM"; break;
25602 		    case VAR_FLOAT:  s = "FLO"; break;
25603 		    case VAR_DICT:   s = "DIC"; break;
25604 		    case VAR_LIST:   s = "LIS"; break;
25605 		    case VAR_SPECIAL: s = "XPL"; break;
25606 
25607 		    case VAR_UNKNOWN:
25608 		    case VAR_FUNC:
25609 		    case VAR_PARTIAL:
25610 		    case VAR_JOB:
25611 		    case VAR_CHANNEL:
25612 				     continue;
25613 		}
25614 		fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
25615 		p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
25616 		if (p != NULL)
25617 		    viminfo_writestring(fp, p);
25618 		vim_free(tofree);
25619 	    }
25620 	}
25621     }
25622 }
25623 #endif
25624 
25625 #if defined(FEAT_SESSION) || defined(PROTO)
25626     int
25627 store_session_globals(FILE *fd)
25628 {
25629     hashitem_T	*hi;
25630     dictitem_T	*this_var;
25631     int		todo;
25632     char_u	*p, *t;
25633 
25634     todo = (int)globvarht.ht_used;
25635     for (hi = globvarht.ht_array; todo > 0; ++hi)
25636     {
25637 	if (!HASHITEM_EMPTY(hi))
25638 	{
25639 	    --todo;
25640 	    this_var = HI2DI(hi);
25641 	    if ((this_var->di_tv.v_type == VAR_NUMBER
25642 			|| this_var->di_tv.v_type == VAR_STRING)
25643 		    && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION)
25644 	    {
25645 		/* Escape special characters with a backslash.  Turn a LF and
25646 		 * CR into \n and \r. */
25647 		p = vim_strsave_escaped(get_tv_string(&this_var->di_tv),
25648 							(char_u *)"\\\"\n\r");
25649 		if (p == NULL)	    /* out of memory */
25650 		    break;
25651 		for (t = p; *t != NUL; ++t)
25652 		    if (*t == '\n')
25653 			*t = 'n';
25654 		    else if (*t == '\r')
25655 			*t = 'r';
25656 		if ((fprintf(fd, "let %s = %c%s%c",
25657 				this_var->di_key,
25658 				(this_var->di_tv.v_type == VAR_STRING) ? '"'
25659 									: ' ',
25660 				p,
25661 				(this_var->di_tv.v_type == VAR_STRING) ? '"'
25662 								   : ' ') < 0)
25663 			|| put_eol(fd) == FAIL)
25664 		{
25665 		    vim_free(p);
25666 		    return FAIL;
25667 		}
25668 		vim_free(p);
25669 	    }
25670 #ifdef FEAT_FLOAT
25671 	    else if (this_var->di_tv.v_type == VAR_FLOAT
25672 		    && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION)
25673 	    {
25674 		float_T f = this_var->di_tv.vval.v_float;
25675 		int sign = ' ';
25676 
25677 		if (f < 0)
25678 		{
25679 		    f = -f;
25680 		    sign = '-';
25681 		}
25682 		if ((fprintf(fd, "let %s = %c%f",
25683 					       this_var->di_key, sign, f) < 0)
25684 			|| put_eol(fd) == FAIL)
25685 		    return FAIL;
25686 	    }
25687 #endif
25688 	}
25689     }
25690     return OK;
25691 }
25692 #endif
25693 
25694 /*
25695  * Display script name where an item was last set.
25696  * Should only be invoked when 'verbose' is non-zero.
25697  */
25698     void
25699 last_set_msg(scid_T scriptID)
25700 {
25701     char_u *p;
25702 
25703     if (scriptID != 0)
25704     {
25705 	p = home_replace_save(NULL, get_scriptname(scriptID));
25706 	if (p != NULL)
25707 	{
25708 	    verbose_enter();
25709 	    MSG_PUTS(_("\n\tLast set from "));
25710 	    MSG_PUTS(p);
25711 	    vim_free(p);
25712 	    verbose_leave();
25713 	}
25714     }
25715 }
25716 
25717 /*
25718  * List v:oldfiles in a nice way.
25719  */
25720     void
25721 ex_oldfiles(exarg_T *eap UNUSED)
25722 {
25723     list_T	*l = vimvars[VV_OLDFILES].vv_list;
25724     listitem_T	*li;
25725     int		nr = 0;
25726 
25727     if (l == NULL)
25728 	msg((char_u *)_("No old files"));
25729     else
25730     {
25731 	msg_start();
25732 	msg_scroll = TRUE;
25733 	for (li = l->lv_first; li != NULL && !got_int; li = li->li_next)
25734 	{
25735 	    msg_outnum((long)++nr);
25736 	    MSG_PUTS(": ");
25737 	    msg_outtrans(get_tv_string(&li->li_tv));
25738 	    msg_putchar('\n');
25739 	    out_flush();	    /* output one line at a time */
25740 	    ui_breakcheck();
25741 	}
25742 	/* Assume "got_int" was set to truncate the listing. */
25743 	got_int = FALSE;
25744 
25745 #ifdef FEAT_BROWSE_CMD
25746 	if (cmdmod.browse)
25747 	{
25748 	    quit_more = FALSE;
25749 	    nr = prompt_for_number(FALSE);
25750 	    msg_starthere();
25751 	    if (nr > 0)
25752 	    {
25753 		char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES),
25754 								    (long)nr);
25755 
25756 		if (p != NULL)
25757 		{
25758 		    p = expand_env_save(p);
25759 		    eap->arg = p;
25760 		    eap->cmdidx = CMD_edit;
25761 		    cmdmod.browse = FALSE;
25762 		    do_exedit(eap, NULL);
25763 		    vim_free(p);
25764 		}
25765 	    }
25766 	}
25767 #endif
25768     }
25769 }
25770 
25771 /* reset v:option_new, v:option_old and v:option_type */
25772     void
25773 reset_v_option_vars(void)
25774 {
25775     set_vim_var_string(VV_OPTION_NEW,  NULL, -1);
25776     set_vim_var_string(VV_OPTION_OLD,  NULL, -1);
25777     set_vim_var_string(VV_OPTION_TYPE, NULL, -1);
25778 }
25779 
25780 
25781 #endif /* FEAT_EVAL */
25782 
25783 
25784 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO)
25785 
25786 #ifdef WIN3264
25787 /*
25788  * Functions for ":8" filename modifier: get 8.3 version of a filename.
25789  */
25790 static int get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen);
25791 static int shortpath_for_invalid_fname(char_u **fname, char_u **bufp, int *fnamelen);
25792 static int shortpath_for_partial(char_u **fnamep, char_u **bufp, int *fnamelen);
25793 
25794 /*
25795  * Get the short path (8.3) for the filename in "fnamep".
25796  * Only works for a valid file name.
25797  * When the path gets longer "fnamep" is changed and the allocated buffer
25798  * is put in "bufp".
25799  * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path.
25800  * Returns OK on success, FAIL on failure.
25801  */
25802     static int
25803 get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen)
25804 {
25805     int		l, len;
25806     char_u	*newbuf;
25807 
25808     len = *fnamelen;
25809     l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, len);
25810     if (l > len - 1)
25811     {
25812 	/* If that doesn't work (not enough space), then save the string
25813 	 * and try again with a new buffer big enough. */
25814 	newbuf = vim_strnsave(*fnamep, l);
25815 	if (newbuf == NULL)
25816 	    return FAIL;
25817 
25818 	vim_free(*bufp);
25819 	*fnamep = *bufp = newbuf;
25820 
25821 	/* Really should always succeed, as the buffer is big enough. */
25822 	l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, l+1);
25823     }
25824 
25825     *fnamelen = l;
25826     return OK;
25827 }
25828 
25829 /*
25830  * Get the short path (8.3) for the filename in "fname". The converted
25831  * path is returned in "bufp".
25832  *
25833  * Some of the directories specified in "fname" may not exist. This function
25834  * will shorten the existing directories at the beginning of the path and then
25835  * append the remaining non-existing path.
25836  *
25837  * fname - Pointer to the filename to shorten.  On return, contains the
25838  *	   pointer to the shortened pathname
25839  * bufp -  Pointer to an allocated buffer for the filename.
25840  * fnamelen - Length of the filename pointed to by fname
25841  *
25842  * Returns OK on success (or nothing done) and FAIL on failure (out of memory).
25843  */
25844     static int
25845 shortpath_for_invalid_fname(
25846     char_u	**fname,
25847     char_u	**bufp,
25848     int		*fnamelen)
25849 {
25850     char_u	*short_fname, *save_fname, *pbuf_unused;
25851     char_u	*endp, *save_endp;
25852     char_u	ch;
25853     int		old_len, len;
25854     int		new_len, sfx_len;
25855     int		retval = OK;
25856 
25857     /* Make a copy */
25858     old_len = *fnamelen;
25859     save_fname = vim_strnsave(*fname, old_len);
25860     pbuf_unused = NULL;
25861     short_fname = NULL;
25862 
25863     endp = save_fname + old_len - 1; /* Find the end of the copy */
25864     save_endp = endp;
25865 
25866     /*
25867      * Try shortening the supplied path till it succeeds by removing one
25868      * directory at a time from the tail of the path.
25869      */
25870     len = 0;
25871     for (;;)
25872     {
25873 	/* go back one path-separator */
25874 	while (endp > save_fname && !after_pathsep(save_fname, endp + 1))
25875 	    --endp;
25876 	if (endp <= save_fname)
25877 	    break;		/* processed the complete path */
25878 
25879 	/*
25880 	 * Replace the path separator with a NUL and try to shorten the
25881 	 * resulting path.
25882 	 */
25883 	ch = *endp;
25884 	*endp = 0;
25885 	short_fname = save_fname;
25886 	len = (int)STRLEN(short_fname) + 1;
25887 	if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL)
25888 	{
25889 	    retval = FAIL;
25890 	    goto theend;
25891 	}
25892 	*endp = ch;	/* preserve the string */
25893 
25894 	if (len > 0)
25895 	    break;	/* successfully shortened the path */
25896 
25897 	/* failed to shorten the path. Skip the path separator */
25898 	--endp;
25899     }
25900 
25901     if (len > 0)
25902     {
25903 	/*
25904 	 * Succeeded in shortening the path. Now concatenate the shortened
25905 	 * path with the remaining path at the tail.
25906 	 */
25907 
25908 	/* Compute the length of the new path. */
25909 	sfx_len = (int)(save_endp - endp) + 1;
25910 	new_len = len + sfx_len;
25911 
25912 	*fnamelen = new_len;
25913 	vim_free(*bufp);
25914 	if (new_len > old_len)
25915 	{
25916 	    /* There is not enough space in the currently allocated string,
25917 	     * copy it to a buffer big enough. */
25918 	    *fname = *bufp = vim_strnsave(short_fname, new_len);
25919 	    if (*fname == NULL)
25920 	    {
25921 		retval = FAIL;
25922 		goto theend;
25923 	    }
25924 	}
25925 	else
25926 	{
25927 	    /* Transfer short_fname to the main buffer (it's big enough),
25928 	     * unless get_short_pathname() did its work in-place. */
25929 	    *fname = *bufp = save_fname;
25930 	    if (short_fname != save_fname)
25931 		vim_strncpy(save_fname, short_fname, len);
25932 	    save_fname = NULL;
25933 	}
25934 
25935 	/* concat the not-shortened part of the path */
25936 	vim_strncpy(*fname + len, endp, sfx_len);
25937 	(*fname)[new_len] = NUL;
25938     }
25939 
25940 theend:
25941     vim_free(pbuf_unused);
25942     vim_free(save_fname);
25943 
25944     return retval;
25945 }
25946 
25947 /*
25948  * Get a pathname for a partial path.
25949  * Returns OK for success, FAIL for failure.
25950  */
25951     static int
25952 shortpath_for_partial(
25953     char_u	**fnamep,
25954     char_u	**bufp,
25955     int		*fnamelen)
25956 {
25957     int		sepcount, len, tflen;
25958     char_u	*p;
25959     char_u	*pbuf, *tfname;
25960     int		hasTilde;
25961 
25962     /* Count up the path separators from the RHS.. so we know which part
25963      * of the path to return. */
25964     sepcount = 0;
25965     for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p))
25966 	if (vim_ispathsep(*p))
25967 	    ++sepcount;
25968 
25969     /* Need full path first (use expand_env() to remove a "~/") */
25970     hasTilde = (**fnamep == '~');
25971     if (hasTilde)
25972 	pbuf = tfname = expand_env_save(*fnamep);
25973     else
25974 	pbuf = tfname = FullName_save(*fnamep, FALSE);
25975 
25976     len = tflen = (int)STRLEN(tfname);
25977 
25978     if (get_short_pathname(&tfname, &pbuf, &len) == FAIL)
25979 	return FAIL;
25980 
25981     if (len == 0)
25982     {
25983 	/* Don't have a valid filename, so shorten the rest of the
25984 	 * path if we can. This CAN give us invalid 8.3 filenames, but
25985 	 * there's not a lot of point in guessing what it might be.
25986 	 */
25987 	len = tflen;
25988 	if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL)
25989 	    return FAIL;
25990     }
25991 
25992     /* Count the paths backward to find the beginning of the desired string. */
25993     for (p = tfname + len - 1; p >= tfname; --p)
25994     {
25995 #ifdef FEAT_MBYTE
25996 	if (has_mbyte)
25997 	    p -= mb_head_off(tfname, p);
25998 #endif
25999 	if (vim_ispathsep(*p))
26000 	{
26001 	    if (sepcount == 0 || (hasTilde && sepcount == 1))
26002 		break;
26003 	    else
26004 		sepcount --;
26005 	}
26006     }
26007     if (hasTilde)
26008     {
26009 	--p;
26010 	if (p >= tfname)
26011 	    *p = '~';
26012 	else
26013 	    return FAIL;
26014     }
26015     else
26016 	++p;
26017 
26018     /* Copy in the string - p indexes into tfname - allocated at pbuf */
26019     vim_free(*bufp);
26020     *fnamelen = (int)STRLEN(p);
26021     *bufp = pbuf;
26022     *fnamep = p;
26023 
26024     return OK;
26025 }
26026 #endif /* WIN3264 */
26027 
26028 /*
26029  * Adjust a filename, according to a string of modifiers.
26030  * *fnamep must be NUL terminated when called.  When returning, the length is
26031  * determined by *fnamelen.
26032  * Returns VALID_ flags or -1 for failure.
26033  * When there is an error, *fnamep is set to NULL.
26034  */
26035     int
26036 modify_fname(
26037     char_u	*src,		/* string with modifiers */
26038     int		*usedlen,	/* characters after src that are used */
26039     char_u	**fnamep,	/* file name so far */
26040     char_u	**bufp,		/* buffer for allocated file name or NULL */
26041     int		*fnamelen)	/* length of fnamep */
26042 {
26043     int		valid = 0;
26044     char_u	*tail;
26045     char_u	*s, *p, *pbuf;
26046     char_u	dirname[MAXPATHL];
26047     int		c;
26048     int		has_fullname = 0;
26049 #ifdef WIN3264
26050     char_u	*fname_start = *fnamep;
26051     int		has_shortname = 0;
26052 #endif
26053 
26054 repeat:
26055     /* ":p" - full path/file_name */
26056     if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p')
26057     {
26058 	has_fullname = 1;
26059 
26060 	valid |= VALID_PATH;
26061 	*usedlen += 2;
26062 
26063 	/* Expand "~/path" for all systems and "~user/path" for Unix and VMS */
26064 	if ((*fnamep)[0] == '~'
26065 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME))
26066 		&& ((*fnamep)[1] == '/'
26067 # ifdef BACKSLASH_IN_FILENAME
26068 		    || (*fnamep)[1] == '\\'
26069 # endif
26070 		    || (*fnamep)[1] == NUL)
26071 
26072 #endif
26073 	   )
26074 	{
26075 	    *fnamep = expand_env_save(*fnamep);
26076 	    vim_free(*bufp);	/* free any allocated file name */
26077 	    *bufp = *fnamep;
26078 	    if (*fnamep == NULL)
26079 		return -1;
26080 	}
26081 
26082 	/* When "/." or "/.." is used: force expansion to get rid of it. */
26083 	for (p = *fnamep; *p != NUL; mb_ptr_adv(p))
26084 	{
26085 	    if (vim_ispathsep(*p)
26086 		    && p[1] == '.'
26087 		    && (p[2] == NUL
26088 			|| vim_ispathsep(p[2])
26089 			|| (p[2] == '.'
26090 			    && (p[3] == NUL || vim_ispathsep(p[3])))))
26091 		break;
26092 	}
26093 
26094 	/* FullName_save() is slow, don't use it when not needed. */
26095 	if (*p != NUL || !vim_isAbsName(*fnamep))
26096 	{
26097 	    *fnamep = FullName_save(*fnamep, *p != NUL);
26098 	    vim_free(*bufp);	/* free any allocated file name */
26099 	    *bufp = *fnamep;
26100 	    if (*fnamep == NULL)
26101 		return -1;
26102 	}
26103 
26104 #ifdef WIN3264
26105 # if _WIN32_WINNT >= 0x0500
26106 	if (vim_strchr(*fnamep, '~') != NULL)
26107 	{
26108 	    /* Expand 8.3 filename to full path.  Needed to make sure the same
26109 	     * file does not have two different names.
26110 	     * Note: problem does not occur if _WIN32_WINNT < 0x0500. */
26111 	    p = alloc(_MAX_PATH + 1);
26112 	    if (p != NULL)
26113 	    {
26114 		if (GetLongPathName((LPSTR)*fnamep, (LPSTR)p, _MAX_PATH))
26115 		{
26116 		    vim_free(*bufp);
26117 		    *bufp = *fnamep = p;
26118 		}
26119 		else
26120 		    vim_free(p);
26121 	    }
26122 	}
26123 # endif
26124 #endif
26125 	/* Append a path separator to a directory. */
26126 	if (mch_isdir(*fnamep))
26127 	{
26128 	    /* Make room for one or two extra characters. */
26129 	    *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2);
26130 	    vim_free(*bufp);	/* free any allocated file name */
26131 	    *bufp = *fnamep;
26132 	    if (*fnamep == NULL)
26133 		return -1;
26134 	    add_pathsep(*fnamep);
26135 	}
26136     }
26137 
26138     /* ":." - path relative to the current directory */
26139     /* ":~" - path relative to the home directory */
26140     /* ":8" - shortname path - postponed till after */
26141     while (src[*usedlen] == ':'
26142 		  && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8'))
26143     {
26144 	*usedlen += 2;
26145 	if (c == '8')
26146 	{
26147 #ifdef WIN3264
26148 	    has_shortname = 1; /* Postpone this. */
26149 #endif
26150 	    continue;
26151 	}
26152 	pbuf = NULL;
26153 	/* Need full path first (use expand_env() to remove a "~/") */
26154 	if (!has_fullname)
26155 	{
26156 	    if (c == '.' && **fnamep == '~')
26157 		p = pbuf = expand_env_save(*fnamep);
26158 	    else
26159 		p = pbuf = FullName_save(*fnamep, FALSE);
26160 	}
26161 	else
26162 	    p = *fnamep;
26163 
26164 	has_fullname = 0;
26165 
26166 	if (p != NULL)
26167 	{
26168 	    if (c == '.')
26169 	    {
26170 		mch_dirname(dirname, MAXPATHL);
26171 		s = shorten_fname(p, dirname);
26172 		if (s != NULL)
26173 		{
26174 		    *fnamep = s;
26175 		    if (pbuf != NULL)
26176 		    {
26177 			vim_free(*bufp);   /* free any allocated file name */
26178 			*bufp = pbuf;
26179 			pbuf = NULL;
26180 		    }
26181 		}
26182 	    }
26183 	    else
26184 	    {
26185 		home_replace(NULL, p, dirname, MAXPATHL, TRUE);
26186 		/* Only replace it when it starts with '~' */
26187 		if (*dirname == '~')
26188 		{
26189 		    s = vim_strsave(dirname);
26190 		    if (s != NULL)
26191 		    {
26192 			*fnamep = s;
26193 			vim_free(*bufp);
26194 			*bufp = s;
26195 		    }
26196 		}
26197 	    }
26198 	    vim_free(pbuf);
26199 	}
26200     }
26201 
26202     tail = gettail(*fnamep);
26203     *fnamelen = (int)STRLEN(*fnamep);
26204 
26205     /* ":h" - head, remove "/file_name", can be repeated  */
26206     /* Don't remove the first "/" or "c:\" */
26207     while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h')
26208     {
26209 	valid |= VALID_HEAD;
26210 	*usedlen += 2;
26211 	s = get_past_head(*fnamep);
26212 	while (tail > s && after_pathsep(s, tail))
26213 	    mb_ptr_back(*fnamep, tail);
26214 	*fnamelen = (int)(tail - *fnamep);
26215 #ifdef VMS
26216 	if (*fnamelen > 0)
26217 	    *fnamelen += 1; /* the path separator is part of the path */
26218 #endif
26219 	if (*fnamelen == 0)
26220 	{
26221 	    /* Result is empty.  Turn it into "." to make ":cd %:h" work. */
26222 	    p = vim_strsave((char_u *)".");
26223 	    if (p == NULL)
26224 		return -1;
26225 	    vim_free(*bufp);
26226 	    *bufp = *fnamep = tail = p;
26227 	    *fnamelen = 1;
26228 	}
26229 	else
26230 	{
26231 	    while (tail > s && !after_pathsep(s, tail))
26232 		mb_ptr_back(*fnamep, tail);
26233 	}
26234     }
26235 
26236     /* ":8" - shortname  */
26237     if (src[*usedlen] == ':' && src[*usedlen + 1] == '8')
26238     {
26239 	*usedlen += 2;
26240 #ifdef WIN3264
26241 	has_shortname = 1;
26242 #endif
26243     }
26244 
26245 #ifdef WIN3264
26246     /*
26247      * Handle ":8" after we have done 'heads' and before we do 'tails'.
26248      */
26249     if (has_shortname)
26250     {
26251 	/* Copy the string if it is shortened by :h and when it wasn't copied
26252 	 * yet, because we are going to change it in place.  Avoids changing
26253 	 * the buffer name for "%:8". */
26254 	if (*fnamelen < (int)STRLEN(*fnamep) || *fnamep == fname_start)
26255 	{
26256 	    p = vim_strnsave(*fnamep, *fnamelen);
26257 	    if (p == NULL)
26258 		return -1;
26259 	    vim_free(*bufp);
26260 	    *bufp = *fnamep = p;
26261 	}
26262 
26263 	/* Split into two implementations - makes it easier.  First is where
26264 	 * there isn't a full name already, second is where there is. */
26265 	if (!has_fullname && !vim_isAbsName(*fnamep))
26266 	{
26267 	    if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL)
26268 		return -1;
26269 	}
26270 	else
26271 	{
26272 	    int		l = *fnamelen;
26273 
26274 	    /* Simple case, already have the full-name.
26275 	     * Nearly always shorter, so try first time. */
26276 	    if (get_short_pathname(fnamep, bufp, &l) == FAIL)
26277 		return -1;
26278 
26279 	    if (l == 0)
26280 	    {
26281 		/* Couldn't find the filename, search the paths. */
26282 		l = *fnamelen;
26283 		if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL)
26284 		    return -1;
26285 	    }
26286 	    *fnamelen = l;
26287 	}
26288     }
26289 #endif /* WIN3264 */
26290 
26291     /* ":t" - tail, just the basename */
26292     if (src[*usedlen] == ':' && src[*usedlen + 1] == 't')
26293     {
26294 	*usedlen += 2;
26295 	*fnamelen -= (int)(tail - *fnamep);
26296 	*fnamep = tail;
26297     }
26298 
26299     /* ":e" - extension, can be repeated */
26300     /* ":r" - root, without extension, can be repeated */
26301     while (src[*usedlen] == ':'
26302 	    && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r'))
26303     {
26304 	/* find a '.' in the tail:
26305 	 * - for second :e: before the current fname
26306 	 * - otherwise: The last '.'
26307 	 */
26308 	if (src[*usedlen + 1] == 'e' && *fnamep > tail)
26309 	    s = *fnamep - 2;
26310 	else
26311 	    s = *fnamep + *fnamelen - 1;
26312 	for ( ; s > tail; --s)
26313 	    if (s[0] == '.')
26314 		break;
26315 	if (src[*usedlen + 1] == 'e')		/* :e */
26316 	{
26317 	    if (s > tail)
26318 	    {
26319 		*fnamelen += (int)(*fnamep - (s + 1));
26320 		*fnamep = s + 1;
26321 #ifdef VMS
26322 		/* cut version from the extension */
26323 		s = *fnamep + *fnamelen - 1;
26324 		for ( ; s > *fnamep; --s)
26325 		    if (s[0] == ';')
26326 			break;
26327 		if (s > *fnamep)
26328 		    *fnamelen = s - *fnamep;
26329 #endif
26330 	    }
26331 	    else if (*fnamep <= tail)
26332 		*fnamelen = 0;
26333 	}
26334 	else				/* :r */
26335 	{
26336 	    if (s > tail)	/* remove one extension */
26337 		*fnamelen = (int)(s - *fnamep);
26338 	}
26339 	*usedlen += 2;
26340     }
26341 
26342     /* ":s?pat?foo?" - substitute */
26343     /* ":gs?pat?foo?" - global substitute */
26344     if (src[*usedlen] == ':'
26345 	    && (src[*usedlen + 1] == 's'
26346 		|| (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's')))
26347     {
26348 	char_u	    *str;
26349 	char_u	    *pat;
26350 	char_u	    *sub;
26351 	int	    sep;
26352 	char_u	    *flags;
26353 	int	    didit = FALSE;
26354 
26355 	flags = (char_u *)"";
26356 	s = src + *usedlen + 2;
26357 	if (src[*usedlen + 1] == 'g')
26358 	{
26359 	    flags = (char_u *)"g";
26360 	    ++s;
26361 	}
26362 
26363 	sep = *s++;
26364 	if (sep)
26365 	{
26366 	    /* find end of pattern */
26367 	    p = vim_strchr(s, sep);
26368 	    if (p != NULL)
26369 	    {
26370 		pat = vim_strnsave(s, (int)(p - s));
26371 		if (pat != NULL)
26372 		{
26373 		    s = p + 1;
26374 		    /* find end of substitution */
26375 		    p = vim_strchr(s, sep);
26376 		    if (p != NULL)
26377 		    {
26378 			sub = vim_strnsave(s, (int)(p - s));
26379 			str = vim_strnsave(*fnamep, *fnamelen);
26380 			if (sub != NULL && str != NULL)
26381 			{
26382 			    *usedlen = (int)(p + 1 - src);
26383 			    s = do_string_sub(str, pat, sub, flags);
26384 			    if (s != NULL)
26385 			    {
26386 				*fnamep = s;
26387 				*fnamelen = (int)STRLEN(s);
26388 				vim_free(*bufp);
26389 				*bufp = s;
26390 				didit = TRUE;
26391 			    }
26392 			}
26393 			vim_free(sub);
26394 			vim_free(str);
26395 		    }
26396 		    vim_free(pat);
26397 		}
26398 	    }
26399 	    /* after using ":s", repeat all the modifiers */
26400 	    if (didit)
26401 		goto repeat;
26402 	}
26403     }
26404 
26405     if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S')
26406     {
26407 	p = vim_strsave_shellescape(*fnamep, FALSE, FALSE);
26408 	if (p == NULL)
26409 	    return -1;
26410 	vim_free(*bufp);
26411 	*bufp = *fnamep = p;
26412 	*fnamelen = (int)STRLEN(p);
26413 	*usedlen += 2;
26414     }
26415 
26416     return valid;
26417 }
26418 
26419 /*
26420  * Perform a substitution on "str" with pattern "pat" and substitute "sub".
26421  * "flags" can be "g" to do a global substitute.
26422  * Returns an allocated string, NULL for error.
26423  */
26424     char_u *
26425 do_string_sub(
26426     char_u	*str,
26427     char_u	*pat,
26428     char_u	*sub,
26429     char_u	*flags)
26430 {
26431     int		sublen;
26432     regmatch_T	regmatch;
26433     int		i;
26434     int		do_all;
26435     char_u	*tail;
26436     char_u	*end;
26437     garray_T	ga;
26438     char_u	*ret;
26439     char_u	*save_cpo;
26440     char_u	*zero_width = NULL;
26441 
26442     /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */
26443     save_cpo = p_cpo;
26444     p_cpo = empty_option;
26445 
26446     ga_init2(&ga, 1, 200);
26447 
26448     do_all = (flags[0] == 'g');
26449 
26450     regmatch.rm_ic = p_ic;
26451     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
26452     if (regmatch.regprog != NULL)
26453     {
26454 	tail = str;
26455 	end = str + STRLEN(str);
26456 	while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
26457 	{
26458 	    /* Skip empty match except for first match. */
26459 	    if (regmatch.startp[0] == regmatch.endp[0])
26460 	    {
26461 		if (zero_width == regmatch.startp[0])
26462 		{
26463 		    /* avoid getting stuck on a match with an empty string */
26464 		    i = MB_PTR2LEN(tail);
26465 		    mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail,
26466 								   (size_t)i);
26467 		    ga.ga_len += i;
26468 		    tail += i;
26469 		    continue;
26470 		}
26471 		zero_width = regmatch.startp[0];
26472 	    }
26473 
26474 	    /*
26475 	     * Get some space for a temporary buffer to do the substitution
26476 	     * into.  It will contain:
26477 	     * - The text up to where the match is.
26478 	     * - The substituted text.
26479 	     * - The text after the match.
26480 	     */
26481 	    sublen = vim_regsub(&regmatch, sub, tail, FALSE, TRUE, FALSE);
26482 	    if (ga_grow(&ga, (int)((end - tail) + sublen -
26483 			    (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
26484 	    {
26485 		ga_clear(&ga);
26486 		break;
26487 	    }
26488 
26489 	    /* copy the text up to where the match is */
26490 	    i = (int)(regmatch.startp[0] - tail);
26491 	    mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
26492 	    /* add the substituted text */
26493 	    (void)vim_regsub(&regmatch, sub, (char_u *)ga.ga_data
26494 					  + ga.ga_len + i, TRUE, TRUE, FALSE);
26495 	    ga.ga_len += i + sublen - 1;
26496 	    tail = regmatch.endp[0];
26497 	    if (*tail == NUL)
26498 		break;
26499 	    if (!do_all)
26500 		break;
26501 	}
26502 
26503 	if (ga.ga_data != NULL)
26504 	    STRCPY((char *)ga.ga_data + ga.ga_len, tail);
26505 
26506 	vim_regfree(regmatch.regprog);
26507     }
26508 
26509     ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
26510     ga_clear(&ga);
26511     if (p_cpo == empty_option)
26512 	p_cpo = save_cpo;
26513     else
26514 	/* Darn, evaluating {sub} expression changed the value. */
26515 	free_string_option(save_cpo);
26516 
26517     return ret;
26518 }
26519 
26520 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */
26521