xref: /vim-8.2.3635/src/eval.c (revision e1012049)
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * eval.c: Expression evaluation.
12  */
13 #define USING_FLOAT_STUFF
14 
15 #include "vim.h"
16 
17 #if defined(FEAT_EVAL) || defined(PROTO)
18 
19 #ifdef AMIGA
20 # include <time.h>	/* for strftime() */
21 #endif
22 
23 #ifdef VMS
24 # include <float.h>
25 #endif
26 
27 #ifdef MACOS
28 # include <time.h>	/* for time_t */
29 #endif
30 
31 #define DICT_MAXNEST 100	/* maximum nesting of lists and dicts */
32 
33 #define DO_NOT_FREE_CNT 99999	/* refcount for dict or list that should not
34 				   be freed. */
35 
36 /*
37  * In a hashtab item "hi_key" points to "di_key" in a dictitem.
38  * This avoids adding a pointer to the hashtab item.
39  * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer.
40  * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer.
41  * HI2DI() converts a hashitem pointer to a dictitem pointer.
42  */
43 static dictitem_T dumdi;
44 #define DI2HIKEY(di) ((di)->di_key)
45 #define HIKEY2DI(p)  ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi)))
46 #define HI2DI(hi)     HIKEY2DI((hi)->hi_key)
47 
48 /*
49  * Structure returned by get_lval() and used by set_var_lval().
50  * For a plain name:
51  *	"name"	    points to the variable name.
52  *	"exp_name"  is NULL.
53  *	"tv"	    is NULL
54  * For a magic braces name:
55  *	"name"	    points to the expanded variable name.
56  *	"exp_name"  is non-NULL, to be freed later.
57  *	"tv"	    is NULL
58  * For an index in a list:
59  *	"name"	    points to the (expanded) variable name.
60  *	"exp_name"  NULL or non-NULL, to be freed later.
61  *	"tv"	    points to the (first) list item value
62  *	"li"	    points to the (first) list item
63  *	"range", "n1", "n2" and "empty2" indicate what items are used.
64  * For an existing Dict item:
65  *	"name"	    points to the (expanded) variable name.
66  *	"exp_name"  NULL or non-NULL, to be freed later.
67  *	"tv"	    points to the dict item value
68  *	"newkey"    is NULL
69  * For a non-existing Dict item:
70  *	"name"	    points to the (expanded) variable name.
71  *	"exp_name"  NULL or non-NULL, to be freed later.
72  *	"tv"	    points to the Dictionary typval_T
73  *	"newkey"    is the key for the new item.
74  */
75 typedef struct lval_S
76 {
77     char_u	*ll_name;	/* start of variable name (can be NULL) */
78     char_u	*ll_exp_name;	/* NULL or expanded name in allocated memory. */
79     typval_T	*ll_tv;		/* Typeval of item being used.  If "newkey"
80 				   isn't NULL it's the Dict to which to add
81 				   the item. */
82     listitem_T	*ll_li;		/* The list item or NULL. */
83     list_T	*ll_list;	/* The list or NULL. */
84     int		ll_range;	/* TRUE when a [i:j] range was used */
85     long	ll_n1;		/* First index for list */
86     long	ll_n2;		/* Second index for list range */
87     int		ll_empty2;	/* Second index is empty: [i:] */
88     dict_T	*ll_dict;	/* The Dictionary or NULL */
89     dictitem_T	*ll_di;		/* The dictitem or NULL */
90     char_u	*ll_newkey;	/* New key for Dict in alloc. mem or NULL. */
91 } lval_T;
92 
93 static char *e_letunexp	= N_("E18: Unexpected characters in :let");
94 static char *e_listidx = N_("E684: list index out of range: %ld");
95 static char *e_undefvar = N_("E121: Undefined variable: %s");
96 static char *e_missbrac = N_("E111: Missing ']'");
97 static char *e_listarg = N_("E686: Argument of %s must be a List");
98 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary");
99 static char *e_listreq = N_("E714: List required");
100 static char *e_dictreq = N_("E715: Dictionary required");
101 static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
102 static char *e_dictkey = N_("E716: Key not present in Dictionary: %s");
103 static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
104 static char *e_funcdict = N_("E717: Dictionary entry already exists");
105 static char *e_funcref = N_("E718: Funcref required");
106 static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
107 static char *e_letwrong = N_("E734: Wrong variable type for %s=");
108 static char *e_nofunc = N_("E130: Unknown function: %s");
109 static char *e_illvar = N_("E461: Illegal variable name: %s");
110 #ifdef FEAT_FLOAT
111 static char *e_float_as_string = N_("E806: using Float as a String");
112 #endif
113 
114 #define NAMESPACE_CHAR	(char_u *)"abglstvw"
115 
116 static dictitem_T	globvars_var;		/* variable used for g: */
117 #define globvarht globvardict.dv_hashtab
118 
119 /*
120  * Old Vim variables such as "v:version" are also available without the "v:".
121  * Also in functions.  We need a special hashtable for them.
122  */
123 static hashtab_T	compat_hashtab;
124 
125 /*
126  * When recursively copying lists and dicts we need to remember which ones we
127  * have done to avoid endless recursiveness.  This unique ID is used for that.
128  * The last bit is used for previous_funccal, ignored when comparing.
129  */
130 static int current_copyID = 0;
131 #define COPYID_INC 2
132 #define COPYID_MASK (~0x1)
133 
134 /* Abort conversion to string after a recursion error. */
135 static int  did_echo_string_emsg = FALSE;
136 
137 /*
138  * Array to hold the hashtab with variables local to each sourced script.
139  * Each item holds a variable (nameless) that points to the dict_T.
140  */
141 typedef struct
142 {
143     dictitem_T	sv_var;
144     dict_T	sv_dict;
145 } scriptvar_T;
146 
147 static garray_T	    ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
148 #define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1])
149 #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
150 
151 static int echo_attr = 0;   /* attributes used for ":echo" */
152 
153 /* Values for trans_function_name() argument: */
154 #define TFN_INT		1	/* internal function name OK */
155 #define TFN_QUIET	2	/* no error messages */
156 #define TFN_NO_AUTOLOAD	4	/* do not use script autoloading */
157 
158 /* Values for get_lval() flags argument: */
159 #define GLV_QUIET	TFN_QUIET	/* no error messages */
160 #define GLV_NO_AUTOLOAD	TFN_NO_AUTOLOAD	/* do not use script autoloading */
161 
162 /*
163  * Structure to hold info for a user function.
164  */
165 typedef struct ufunc ufunc_T;
166 
167 struct ufunc
168 {
169     int		uf_varargs;	/* variable nr of arguments */
170     int		uf_flags;
171     int		uf_calls;	/* nr of active calls */
172     garray_T	uf_args;	/* arguments */
173     garray_T	uf_lines;	/* function lines */
174 #ifdef FEAT_PROFILE
175     int		uf_profiling;	/* TRUE when func is being profiled */
176     /* profiling the function as a whole */
177     int		uf_tm_count;	/* nr of calls */
178     proftime_T	uf_tm_total;	/* time spent in function + children */
179     proftime_T	uf_tm_self;	/* time spent in function itself */
180     proftime_T	uf_tm_children;	/* time spent in children this call */
181     /* profiling the function per line */
182     int		*uf_tml_count;	/* nr of times line was executed */
183     proftime_T	*uf_tml_total;	/* time spent in a line + children */
184     proftime_T	*uf_tml_self;	/* time spent in a line itself */
185     proftime_T	uf_tml_start;	/* start time for current line */
186     proftime_T	uf_tml_children; /* time spent in children for this line */
187     proftime_T	uf_tml_wait;	/* start wait time for current line */
188     int		uf_tml_idx;	/* index of line being timed; -1 if none */
189     int		uf_tml_execed;	/* line being timed was executed */
190 #endif
191     scid_T	uf_script_ID;	/* ID of script where function was defined,
192 				   used for s: variables */
193     int		uf_refcount;	/* for numbered function: reference count */
194     char_u	uf_name[1];	/* name of function (actually longer); can
195 				   start with <SNR>123_ (<SNR> is K_SPECIAL
196 				   KS_EXTRA KE_SNR) */
197 };
198 
199 /* function flags */
200 #define FC_ABORT    1		/* abort function on error */
201 #define FC_RANGE    2		/* function accepts range */
202 #define FC_DICT	    4		/* Dict function, uses "self" */
203 
204 /*
205  * All user-defined functions are found in this hashtable.
206  */
207 static hashtab_T	func_hashtab;
208 
209 /* The names of packages that once were loaded are remembered. */
210 static garray_T		ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
211 
212 /* List heads for garbage collection. Although there can be a reference loop
213  * from partial to dict to partial, we don't need to keep track of the partial,
214  * since it will get freed when the dict is unused and gets freed. */
215 static dict_T		*first_dict = NULL;	/* list of all dicts */
216 static list_T		*first_list = NULL;	/* list of all lists */
217 
218 /* From user function to hashitem and back. */
219 static ufunc_T dumuf;
220 #define UF2HIKEY(fp) ((fp)->uf_name)
221 #define HIKEY2UF(p)  ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf)))
222 #define HI2UF(hi)     HIKEY2UF((hi)->hi_key)
223 
224 #define FUNCARG(fp, j)	((char_u **)(fp->uf_args.ga_data))[j]
225 #define FUNCLINE(fp, j)	((char_u **)(fp->uf_lines.ga_data))[j]
226 
227 #define MAX_FUNC_ARGS	20	/* maximum number of function arguments */
228 #define VAR_SHORT_LEN	20	/* short variable name length */
229 #define FIXVAR_CNT	12	/* number of fixed variables */
230 
231 /* structure to hold info for a function that is currently being executed. */
232 typedef struct funccall_S funccall_T;
233 
234 struct funccall_S
235 {
236     ufunc_T	*func;		/* function being called */
237     int		linenr;		/* next line to be executed */
238     int		returned;	/* ":return" used */
239     struct			/* fixed variables for arguments */
240     {
241 	dictitem_T	var;		/* variable (without room for name) */
242 	char_u	room[VAR_SHORT_LEN];	/* room for the name */
243     } fixvar[FIXVAR_CNT];
244     dict_T	l_vars;		/* l: local function variables */
245     dictitem_T	l_vars_var;	/* variable for l: scope */
246     dict_T	l_avars;	/* a: argument variables */
247     dictitem_T	l_avars_var;	/* variable for a: scope */
248     list_T	l_varlist;	/* list for a:000 */
249     listitem_T	l_listitems[MAX_FUNC_ARGS];	/* listitems for a:000 */
250     typval_T	*rettv;		/* return value */
251     linenr_T	breakpoint;	/* next line with breakpoint or zero */
252     int		dbg_tick;	/* debug_tick when breakpoint was set */
253     int		level;		/* top nesting level of executed function */
254 #ifdef FEAT_PROFILE
255     proftime_T	prof_child;	/* time spent in a child */
256 #endif
257     funccall_T	*caller;	/* calling function or NULL */
258 };
259 
260 /*
261  * Info used by a ":for" loop.
262  */
263 typedef struct
264 {
265     int		fi_semicolon;	/* TRUE if ending in '; var]' */
266     int		fi_varcount;	/* nr of variables in the list */
267     listwatch_T	fi_lw;		/* keep an eye on the item used. */
268     list_T	*fi_list;	/* list being used */
269 } forinfo_T;
270 
271 /*
272  * Struct used by trans_function_name()
273  */
274 typedef struct
275 {
276     dict_T	*fd_dict;	/* Dictionary used */
277     char_u	*fd_newkey;	/* new key in "dict" in allocated memory */
278     dictitem_T	*fd_di;		/* Dictionary item used */
279 } funcdict_T;
280 
281 
282 /*
283  * Array to hold the value of v: variables.
284  * The value is in a dictitem, so that it can also be used in the v: scope.
285  * The reason to use this table anyway is for very quick access to the
286  * variables with the VV_ defines.
287  */
288 #include "version.h"
289 
290 /* values for vv_flags: */
291 #define VV_COMPAT	1	/* compatible, also used without "v:" */
292 #define VV_RO		2	/* read-only */
293 #define VV_RO_SBX	4	/* read-only in the sandbox */
294 
295 #define VV_NAME(s, t)	s, {{t, 0, {0}}, 0, {0}}
296 
297 static struct vimvar
298 {
299     char	*vv_name;	/* name of variable, without v: */
300     dictitem16_T vv_di;		/* value and name for key (max 16 chars!) */
301     char	vv_flags;	/* VV_COMPAT, VV_RO, VV_RO_SBX */
302 } vimvars[VV_LEN] =
303 {
304     /*
305      * The order here must match the VV_ defines in vim.h!
306      * Initializing a union does not work, leave tv.vval empty to get zero's.
307      */
308     {VV_NAME("count",		 VAR_NUMBER), VV_COMPAT+VV_RO},
309     {VV_NAME("count1",		 VAR_NUMBER), VV_RO},
310     {VV_NAME("prevcount",	 VAR_NUMBER), VV_RO},
311     {VV_NAME("errmsg",		 VAR_STRING), VV_COMPAT},
312     {VV_NAME("warningmsg",	 VAR_STRING), 0},
313     {VV_NAME("statusmsg",	 VAR_STRING), 0},
314     {VV_NAME("shell_error",	 VAR_NUMBER), VV_COMPAT+VV_RO},
315     {VV_NAME("this_session",	 VAR_STRING), VV_COMPAT},
316     {VV_NAME("version",		 VAR_NUMBER), VV_COMPAT+VV_RO},
317     {VV_NAME("lnum",		 VAR_NUMBER), VV_RO_SBX},
318     {VV_NAME("termresponse",	 VAR_STRING), VV_RO},
319     {VV_NAME("fname",		 VAR_STRING), VV_RO},
320     {VV_NAME("lang",		 VAR_STRING), VV_RO},
321     {VV_NAME("lc_time",		 VAR_STRING), VV_RO},
322     {VV_NAME("ctype",		 VAR_STRING), VV_RO},
323     {VV_NAME("charconvert_from", VAR_STRING), VV_RO},
324     {VV_NAME("charconvert_to",	 VAR_STRING), VV_RO},
325     {VV_NAME("fname_in",	 VAR_STRING), VV_RO},
326     {VV_NAME("fname_out",	 VAR_STRING), VV_RO},
327     {VV_NAME("fname_new",	 VAR_STRING), VV_RO},
328     {VV_NAME("fname_diff",	 VAR_STRING), VV_RO},
329     {VV_NAME("cmdarg",		 VAR_STRING), VV_RO},
330     {VV_NAME("foldstart",	 VAR_NUMBER), VV_RO_SBX},
331     {VV_NAME("foldend",		 VAR_NUMBER), VV_RO_SBX},
332     {VV_NAME("folddashes",	 VAR_STRING), VV_RO_SBX},
333     {VV_NAME("foldlevel",	 VAR_NUMBER), VV_RO_SBX},
334     {VV_NAME("progname",	 VAR_STRING), VV_RO},
335     {VV_NAME("servername",	 VAR_STRING), VV_RO},
336     {VV_NAME("dying",		 VAR_NUMBER), VV_RO},
337     {VV_NAME("exception",	 VAR_STRING), VV_RO},
338     {VV_NAME("throwpoint",	 VAR_STRING), VV_RO},
339     {VV_NAME("register",	 VAR_STRING), VV_RO},
340     {VV_NAME("cmdbang",		 VAR_NUMBER), VV_RO},
341     {VV_NAME("insertmode",	 VAR_STRING), VV_RO},
342     {VV_NAME("val",		 VAR_UNKNOWN), VV_RO},
343     {VV_NAME("key",		 VAR_UNKNOWN), VV_RO},
344     {VV_NAME("profiling",	 VAR_NUMBER), VV_RO},
345     {VV_NAME("fcs_reason",	 VAR_STRING), VV_RO},
346     {VV_NAME("fcs_choice",	 VAR_STRING), 0},
347     {VV_NAME("beval_bufnr",	 VAR_NUMBER), VV_RO},
348     {VV_NAME("beval_winnr",	 VAR_NUMBER), VV_RO},
349     {VV_NAME("beval_lnum",	 VAR_NUMBER), VV_RO},
350     {VV_NAME("beval_col",	 VAR_NUMBER), VV_RO},
351     {VV_NAME("beval_text",	 VAR_STRING), VV_RO},
352     {VV_NAME("scrollstart",	 VAR_STRING), 0},
353     {VV_NAME("swapname",	 VAR_STRING), VV_RO},
354     {VV_NAME("swapchoice",	 VAR_STRING), 0},
355     {VV_NAME("swapcommand",	 VAR_STRING), VV_RO},
356     {VV_NAME("char",		 VAR_STRING), 0},
357     {VV_NAME("mouse_win",	 VAR_NUMBER), 0},
358     {VV_NAME("mouse_lnum",	 VAR_NUMBER), 0},
359     {VV_NAME("mouse_col",	 VAR_NUMBER), 0},
360     {VV_NAME("operator",	 VAR_STRING), VV_RO},
361     {VV_NAME("searchforward",	 VAR_NUMBER), 0},
362     {VV_NAME("hlsearch",	 VAR_NUMBER), 0},
363     {VV_NAME("oldfiles",	 VAR_LIST), 0},
364     {VV_NAME("windowid",	 VAR_NUMBER), VV_RO},
365     {VV_NAME("progpath",	 VAR_STRING), VV_RO},
366     {VV_NAME("completed_item",	 VAR_DICT), VV_RO},
367     {VV_NAME("option_new",	 VAR_STRING), VV_RO},
368     {VV_NAME("option_old",	 VAR_STRING), VV_RO},
369     {VV_NAME("option_type",	 VAR_STRING), VV_RO},
370     {VV_NAME("errors",		 VAR_LIST), 0},
371     {VV_NAME("false",		 VAR_SPECIAL), VV_RO},
372     {VV_NAME("true",		 VAR_SPECIAL), VV_RO},
373     {VV_NAME("null",		 VAR_SPECIAL), VV_RO},
374     {VV_NAME("none",		 VAR_SPECIAL), VV_RO},
375     {VV_NAME("vim_did_enter",	 VAR_NUMBER), VV_RO},
376 };
377 
378 /* shorthand */
379 #define vv_type		vv_di.di_tv.v_type
380 #define vv_nr		vv_di.di_tv.vval.v_number
381 #define vv_float	vv_di.di_tv.vval.v_float
382 #define vv_str		vv_di.di_tv.vval.v_string
383 #define vv_list		vv_di.di_tv.vval.v_list
384 #define vv_dict		vv_di.di_tv.vval.v_dict
385 #define vv_tv		vv_di.di_tv
386 
387 static dictitem_T	vimvars_var;		/* variable used for v: */
388 #define vimvarht  vimvardict.dv_hashtab
389 
390 static void prepare_vimvar(int idx, typval_T *save_tv);
391 static void restore_vimvar(int idx, typval_T *save_tv);
392 static int ex_let_vars(char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars);
393 static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon);
394 static char_u *skip_var_one(char_u *arg);
395 static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first);
396 static void list_glob_vars(int *first);
397 static void list_buf_vars(int *first);
398 static void list_win_vars(int *first);
399 #ifdef FEAT_WINDOWS
400 static void list_tab_vars(int *first);
401 #endif
402 static void list_vim_vars(int *first);
403 static void list_script_vars(int *first);
404 static void list_func_vars(int *first);
405 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first);
406 static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op);
407 static int check_changedtick(char_u *arg);
408 static char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags);
409 static void clear_lval(lval_T *lp);
410 static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op);
411 static int tv_op(typval_T *tv1, typval_T *tv2, char_u  *op);
412 static void list_fix_watch(list_T *l, listitem_T *item);
413 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep);
414 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit);
415 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock);
416 static void item_lock(typval_T *tv, int deep, int lock);
417 static int tv_islocked(typval_T *tv);
418 
419 static int eval0(char_u *arg,  typval_T *rettv, char_u **nextcmd, int evaluate);
420 static int eval1(char_u **arg, typval_T *rettv, int evaluate);
421 static int eval2(char_u **arg, typval_T *rettv, int evaluate);
422 static int eval3(char_u **arg, typval_T *rettv, int evaluate);
423 static int eval4(char_u **arg, typval_T *rettv, int evaluate);
424 static int eval5(char_u **arg, typval_T *rettv, int evaluate);
425 static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string);
426 static int eval7(char_u **arg, typval_T *rettv, int evaluate, int want_string);
427 
428 static int eval_index(char_u **arg, typval_T *rettv, int evaluate, int verbose);
429 static int get_option_tv(char_u **arg, typval_T *rettv, int evaluate);
430 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate);
431 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate);
432 static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate);
433 static long list_len(list_T *l);
434 static int list_equal(list_T *l1, list_T *l2, int ic, int recursive);
435 static int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive);
436 static int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
437 static long list_find_nr(list_T *l, long idx, int *errorp);
438 static long list_idx_of_item(list_T *l, listitem_T *item);
439 static int list_extend(list_T	*l1, list_T *l2, listitem_T *bef);
440 static int list_concat(list_T *l1, list_T *l2, typval_T *tv);
441 static list_T *list_copy(list_T *orig, int deep, int copyID);
442 static char_u *list2string(typval_T *tv, int copyID);
443 static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap);
444 static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo, int copyID);
445 static int free_unref_items(int copyID);
446 static dictitem_T *dictitem_copy(dictitem_T *org);
447 static void dictitem_remove(dict_T *dict, dictitem_T *item);
448 static dict_T *dict_copy(dict_T *orig, int deep, int copyID);
449 static long dict_len(dict_T *d);
450 static char_u *dict2string(typval_T *tv, int copyID);
451 static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate);
452 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
453 static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
454 static char_u *string_quote(char_u *str, int function);
455 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
456 static int find_internal_func(char_u *name);
457 static char_u *deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload);
458 static int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict);
459 static void emsg_funcname(char *ermsg, char_u *name);
460 static int non_zero_arg(typval_T *argvars);
461 
462 #ifdef FEAT_FLOAT
463 static void f_abs(typval_T *argvars, typval_T *rettv);
464 static void f_acos(typval_T *argvars, typval_T *rettv);
465 #endif
466 static void f_add(typval_T *argvars, typval_T *rettv);
467 static void f_alloc_fail(typval_T *argvars, typval_T *rettv);
468 static void f_and(typval_T *argvars, typval_T *rettv);
469 static void f_append(typval_T *argvars, typval_T *rettv);
470 static void f_argc(typval_T *argvars, typval_T *rettv);
471 static void f_argidx(typval_T *argvars, typval_T *rettv);
472 static void f_arglistid(typval_T *argvars, typval_T *rettv);
473 static void f_argv(typval_T *argvars, typval_T *rettv);
474 static void f_assert_equal(typval_T *argvars, typval_T *rettv);
475 static void f_assert_exception(typval_T *argvars, typval_T *rettv);
476 static void f_assert_fails(typval_T *argvars, typval_T *rettv);
477 static void f_assert_false(typval_T *argvars, typval_T *rettv);
478 static void f_assert_match(typval_T *argvars, typval_T *rettv);
479 static void f_assert_true(typval_T *argvars, typval_T *rettv);
480 #ifdef FEAT_FLOAT
481 static void f_asin(typval_T *argvars, typval_T *rettv);
482 static void f_atan(typval_T *argvars, typval_T *rettv);
483 static void f_atan2(typval_T *argvars, typval_T *rettv);
484 #endif
485 static void f_browse(typval_T *argvars, typval_T *rettv);
486 static void f_browsedir(typval_T *argvars, typval_T *rettv);
487 static void f_bufexists(typval_T *argvars, typval_T *rettv);
488 static void f_buflisted(typval_T *argvars, typval_T *rettv);
489 static void f_bufloaded(typval_T *argvars, typval_T *rettv);
490 static void f_bufname(typval_T *argvars, typval_T *rettv);
491 static void f_bufnr(typval_T *argvars, typval_T *rettv);
492 static void f_bufwinnr(typval_T *argvars, typval_T *rettv);
493 static void f_byte2line(typval_T *argvars, typval_T *rettv);
494 static void byteidx(typval_T *argvars, typval_T *rettv, int comp);
495 static void f_byteidx(typval_T *argvars, typval_T *rettv);
496 static void f_byteidxcomp(typval_T *argvars, typval_T *rettv);
497 static void f_call(typval_T *argvars, typval_T *rettv);
498 #ifdef FEAT_FLOAT
499 static void f_ceil(typval_T *argvars, typval_T *rettv);
500 #endif
501 #ifdef FEAT_JOB_CHANNEL
502 static void f_ch_close(typval_T *argvars, typval_T *rettv);
503 static void f_ch_evalexpr(typval_T *argvars, typval_T *rettv);
504 static void f_ch_evalraw(typval_T *argvars, typval_T *rettv);
505 static void f_ch_getbufnr(typval_T *argvars, typval_T *rettv);
506 static void f_ch_getjob(typval_T *argvars, typval_T *rettv);
507 static void f_ch_info(typval_T *argvars, typval_T *rettv);
508 static void f_ch_log(typval_T *argvars, typval_T *rettv);
509 static void f_ch_logfile(typval_T *argvars, typval_T *rettv);
510 static void f_ch_open(typval_T *argvars, typval_T *rettv);
511 static void f_ch_read(typval_T *argvars, typval_T *rettv);
512 static void f_ch_readraw(typval_T *argvars, typval_T *rettv);
513 static void f_ch_sendexpr(typval_T *argvars, typval_T *rettv);
514 static void f_ch_sendraw(typval_T *argvars, typval_T *rettv);
515 static void f_ch_setoptions(typval_T *argvars, typval_T *rettv);
516 static void f_ch_status(typval_T *argvars, typval_T *rettv);
517 #endif
518 static void f_changenr(typval_T *argvars, typval_T *rettv);
519 static void f_char2nr(typval_T *argvars, typval_T *rettv);
520 static void f_cindent(typval_T *argvars, typval_T *rettv);
521 static void f_clearmatches(typval_T *argvars, typval_T *rettv);
522 static void f_col(typval_T *argvars, typval_T *rettv);
523 #if defined(FEAT_INS_EXPAND)
524 static void f_complete(typval_T *argvars, typval_T *rettv);
525 static void f_complete_add(typval_T *argvars, typval_T *rettv);
526 static void f_complete_check(typval_T *argvars, typval_T *rettv);
527 #endif
528 static void f_confirm(typval_T *argvars, typval_T *rettv);
529 static void f_copy(typval_T *argvars, typval_T *rettv);
530 #ifdef FEAT_FLOAT
531 static void f_cos(typval_T *argvars, typval_T *rettv);
532 static void f_cosh(typval_T *argvars, typval_T *rettv);
533 #endif
534 static void f_count(typval_T *argvars, typval_T *rettv);
535 static void f_cscope_connection(typval_T *argvars, typval_T *rettv);
536 static void f_cursor(typval_T *argsvars, typval_T *rettv);
537 static void f_deepcopy(typval_T *argvars, typval_T *rettv);
538 static void f_delete(typval_T *argvars, typval_T *rettv);
539 static void f_did_filetype(typval_T *argvars, typval_T *rettv);
540 static void f_diff_filler(typval_T *argvars, typval_T *rettv);
541 static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
542 static void f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv);
543 static void f_empty(typval_T *argvars, typval_T *rettv);
544 static void f_escape(typval_T *argvars, typval_T *rettv);
545 static void f_eval(typval_T *argvars, typval_T *rettv);
546 static void f_eventhandler(typval_T *argvars, typval_T *rettv);
547 static void f_executable(typval_T *argvars, typval_T *rettv);
548 static void f_exepath(typval_T *argvars, typval_T *rettv);
549 static void f_exists(typval_T *argvars, typval_T *rettv);
550 #ifdef FEAT_FLOAT
551 static void f_exp(typval_T *argvars, typval_T *rettv);
552 #endif
553 static void f_expand(typval_T *argvars, typval_T *rettv);
554 static void f_extend(typval_T *argvars, typval_T *rettv);
555 static void f_feedkeys(typval_T *argvars, typval_T *rettv);
556 static void f_filereadable(typval_T *argvars, typval_T *rettv);
557 static void f_filewritable(typval_T *argvars, typval_T *rettv);
558 static void f_filter(typval_T *argvars, typval_T *rettv);
559 static void f_finddir(typval_T *argvars, typval_T *rettv);
560 static void f_findfile(typval_T *argvars, typval_T *rettv);
561 #ifdef FEAT_FLOAT
562 static void f_float2nr(typval_T *argvars, typval_T *rettv);
563 static void f_floor(typval_T *argvars, typval_T *rettv);
564 static void f_fmod(typval_T *argvars, typval_T *rettv);
565 #endif
566 static void f_fnameescape(typval_T *argvars, typval_T *rettv);
567 static void f_fnamemodify(typval_T *argvars, typval_T *rettv);
568 static void f_foldclosed(typval_T *argvars, typval_T *rettv);
569 static void f_foldclosedend(typval_T *argvars, typval_T *rettv);
570 static void f_foldlevel(typval_T *argvars, typval_T *rettv);
571 static void f_foldtext(typval_T *argvars, typval_T *rettv);
572 static void f_foldtextresult(typval_T *argvars, typval_T *rettv);
573 static void f_foreground(typval_T *argvars, typval_T *rettv);
574 static void f_function(typval_T *argvars, typval_T *rettv);
575 static void f_garbagecollect(typval_T *argvars, typval_T *rettv);
576 static void f_get(typval_T *argvars, typval_T *rettv);
577 static void f_getbufline(typval_T *argvars, typval_T *rettv);
578 static void f_getbufvar(typval_T *argvars, typval_T *rettv);
579 static void f_getchar(typval_T *argvars, typval_T *rettv);
580 static void f_getcharmod(typval_T *argvars, typval_T *rettv);
581 static void f_getcharsearch(typval_T *argvars, typval_T *rettv);
582 static void f_getcmdline(typval_T *argvars, typval_T *rettv);
583 static void f_getcmdpos(typval_T *argvars, typval_T *rettv);
584 static void f_getcmdtype(typval_T *argvars, typval_T *rettv);
585 static void f_getcmdwintype(typval_T *argvars, typval_T *rettv);
586 static void f_getcwd(typval_T *argvars, typval_T *rettv);
587 static void f_getfontname(typval_T *argvars, typval_T *rettv);
588 static void f_getfperm(typval_T *argvars, typval_T *rettv);
589 static void f_getfsize(typval_T *argvars, typval_T *rettv);
590 static void f_getftime(typval_T *argvars, typval_T *rettv);
591 static void f_getftype(typval_T *argvars, typval_T *rettv);
592 static void f_getline(typval_T *argvars, typval_T *rettv);
593 static void f_getmatches(typval_T *argvars, typval_T *rettv);
594 static void f_getpid(typval_T *argvars, typval_T *rettv);
595 static void f_getcurpos(typval_T *argvars, typval_T *rettv);
596 static void f_getpos(typval_T *argvars, typval_T *rettv);
597 static void f_getqflist(typval_T *argvars, typval_T *rettv);
598 static void f_getreg(typval_T *argvars, typval_T *rettv);
599 static void f_getregtype(typval_T *argvars, typval_T *rettv);
600 static void f_gettabvar(typval_T *argvars, typval_T *rettv);
601 static void f_gettabwinvar(typval_T *argvars, typval_T *rettv);
602 static void f_getwinposx(typval_T *argvars, typval_T *rettv);
603 static void f_getwinposy(typval_T *argvars, typval_T *rettv);
604 static void f_getwinvar(typval_T *argvars, typval_T *rettv);
605 static void f_glob(typval_T *argvars, typval_T *rettv);
606 static void f_globpath(typval_T *argvars, typval_T *rettv);
607 static void f_glob2regpat(typval_T *argvars, typval_T *rettv);
608 static void f_has(typval_T *argvars, typval_T *rettv);
609 static void f_has_key(typval_T *argvars, typval_T *rettv);
610 static void f_haslocaldir(typval_T *argvars, typval_T *rettv);
611 static void f_hasmapto(typval_T *argvars, typval_T *rettv);
612 static void f_histadd(typval_T *argvars, typval_T *rettv);
613 static void f_histdel(typval_T *argvars, typval_T *rettv);
614 static void f_histget(typval_T *argvars, typval_T *rettv);
615 static void f_histnr(typval_T *argvars, typval_T *rettv);
616 static void f_hlID(typval_T *argvars, typval_T *rettv);
617 static void f_hlexists(typval_T *argvars, typval_T *rettv);
618 static void f_hostname(typval_T *argvars, typval_T *rettv);
619 static void f_iconv(typval_T *argvars, typval_T *rettv);
620 static void f_indent(typval_T *argvars, typval_T *rettv);
621 static void f_index(typval_T *argvars, typval_T *rettv);
622 static void f_input(typval_T *argvars, typval_T *rettv);
623 static void f_inputdialog(typval_T *argvars, typval_T *rettv);
624 static void f_inputlist(typval_T *argvars, typval_T *rettv);
625 static void f_inputrestore(typval_T *argvars, typval_T *rettv);
626 static void f_inputsave(typval_T *argvars, typval_T *rettv);
627 static void f_inputsecret(typval_T *argvars, typval_T *rettv);
628 static void f_insert(typval_T *argvars, typval_T *rettv);
629 static void f_invert(typval_T *argvars, typval_T *rettv);
630 static void f_isdirectory(typval_T *argvars, typval_T *rettv);
631 static void f_islocked(typval_T *argvars, typval_T *rettv);
632 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
633 static void f_isnan(typval_T *argvars, typval_T *rettv);
634 #endif
635 static void f_items(typval_T *argvars, typval_T *rettv);
636 #ifdef FEAT_JOB_CHANNEL
637 static void f_job_getchannel(typval_T *argvars, typval_T *rettv);
638 static void f_job_info(typval_T *argvars, typval_T *rettv);
639 static void f_job_setoptions(typval_T *argvars, typval_T *rettv);
640 static void f_job_start(typval_T *argvars, typval_T *rettv);
641 static void f_job_stop(typval_T *argvars, typval_T *rettv);
642 static void f_job_status(typval_T *argvars, typval_T *rettv);
643 #endif
644 static void f_join(typval_T *argvars, typval_T *rettv);
645 static void f_js_decode(typval_T *argvars, typval_T *rettv);
646 static void f_js_encode(typval_T *argvars, typval_T *rettv);
647 static void f_json_decode(typval_T *argvars, typval_T *rettv);
648 static void f_json_encode(typval_T *argvars, typval_T *rettv);
649 static void f_keys(typval_T *argvars, typval_T *rettv);
650 static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv);
651 static void f_len(typval_T *argvars, typval_T *rettv);
652 static void f_libcall(typval_T *argvars, typval_T *rettv);
653 static void f_libcallnr(typval_T *argvars, typval_T *rettv);
654 static void f_line(typval_T *argvars, typval_T *rettv);
655 static void f_line2byte(typval_T *argvars, typval_T *rettv);
656 static void f_lispindent(typval_T *argvars, typval_T *rettv);
657 static void f_localtime(typval_T *argvars, typval_T *rettv);
658 #ifdef FEAT_FLOAT
659 static void f_log(typval_T *argvars, typval_T *rettv);
660 static void f_log10(typval_T *argvars, typval_T *rettv);
661 #endif
662 #ifdef FEAT_LUA
663 static void f_luaeval(typval_T *argvars, typval_T *rettv);
664 #endif
665 static void f_map(typval_T *argvars, typval_T *rettv);
666 static void f_maparg(typval_T *argvars, typval_T *rettv);
667 static void f_mapcheck(typval_T *argvars, typval_T *rettv);
668 static void f_match(typval_T *argvars, typval_T *rettv);
669 static void f_matchadd(typval_T *argvars, typval_T *rettv);
670 static void f_matchaddpos(typval_T *argvars, typval_T *rettv);
671 static void f_matcharg(typval_T *argvars, typval_T *rettv);
672 static void f_matchdelete(typval_T *argvars, typval_T *rettv);
673 static void f_matchend(typval_T *argvars, typval_T *rettv);
674 static void f_matchlist(typval_T *argvars, typval_T *rettv);
675 static void f_matchstr(typval_T *argvars, typval_T *rettv);
676 static void f_max(typval_T *argvars, typval_T *rettv);
677 static void f_min(typval_T *argvars, typval_T *rettv);
678 #ifdef vim_mkdir
679 static void f_mkdir(typval_T *argvars, typval_T *rettv);
680 #endif
681 static void f_mode(typval_T *argvars, typval_T *rettv);
682 #ifdef FEAT_MZSCHEME
683 static void f_mzeval(typval_T *argvars, typval_T *rettv);
684 #endif
685 static void f_nextnonblank(typval_T *argvars, typval_T *rettv);
686 static void f_nr2char(typval_T *argvars, typval_T *rettv);
687 static void f_or(typval_T *argvars, typval_T *rettv);
688 static void f_pathshorten(typval_T *argvars, typval_T *rettv);
689 #ifdef FEAT_PERL
690 static void f_perleval(typval_T *argvars, typval_T *rettv);
691 #endif
692 #ifdef FEAT_FLOAT
693 static void f_pow(typval_T *argvars, typval_T *rettv);
694 #endif
695 static void f_prevnonblank(typval_T *argvars, typval_T *rettv);
696 static void f_printf(typval_T *argvars, typval_T *rettv);
697 static void f_pumvisible(typval_T *argvars, typval_T *rettv);
698 #ifdef FEAT_PYTHON3
699 static void f_py3eval(typval_T *argvars, typval_T *rettv);
700 #endif
701 #ifdef FEAT_PYTHON
702 static void f_pyeval(typval_T *argvars, typval_T *rettv);
703 #endif
704 static void f_range(typval_T *argvars, typval_T *rettv);
705 static void f_readfile(typval_T *argvars, typval_T *rettv);
706 static void f_reltime(typval_T *argvars, typval_T *rettv);
707 #ifdef FEAT_FLOAT
708 static void f_reltimefloat(typval_T *argvars, typval_T *rettv);
709 #endif
710 static void f_reltimestr(typval_T *argvars, typval_T *rettv);
711 static void f_remote_expr(typval_T *argvars, typval_T *rettv);
712 static void f_remote_foreground(typval_T *argvars, typval_T *rettv);
713 static void f_remote_peek(typval_T *argvars, typval_T *rettv);
714 static void f_remote_read(typval_T *argvars, typval_T *rettv);
715 static void f_remote_send(typval_T *argvars, typval_T *rettv);
716 static void f_remove(typval_T *argvars, typval_T *rettv);
717 static void f_rename(typval_T *argvars, typval_T *rettv);
718 static void f_repeat(typval_T *argvars, typval_T *rettv);
719 static void f_resolve(typval_T *argvars, typval_T *rettv);
720 static void f_reverse(typval_T *argvars, typval_T *rettv);
721 #ifdef FEAT_FLOAT
722 static void f_round(typval_T *argvars, typval_T *rettv);
723 #endif
724 static void f_screenattr(typval_T *argvars, typval_T *rettv);
725 static void f_screenchar(typval_T *argvars, typval_T *rettv);
726 static void f_screencol(typval_T *argvars, typval_T *rettv);
727 static void f_screenrow(typval_T *argvars, typval_T *rettv);
728 static void f_search(typval_T *argvars, typval_T *rettv);
729 static void f_searchdecl(typval_T *argvars, typval_T *rettv);
730 static void f_searchpair(typval_T *argvars, typval_T *rettv);
731 static void f_searchpairpos(typval_T *argvars, typval_T *rettv);
732 static void f_searchpos(typval_T *argvars, typval_T *rettv);
733 static void f_server2client(typval_T *argvars, typval_T *rettv);
734 static void f_serverlist(typval_T *argvars, typval_T *rettv);
735 static void f_setbufvar(typval_T *argvars, typval_T *rettv);
736 static void f_setcharsearch(typval_T *argvars, typval_T *rettv);
737 static void f_setcmdpos(typval_T *argvars, typval_T *rettv);
738 static void f_setfperm(typval_T *argvars, typval_T *rettv);
739 static void f_setline(typval_T *argvars, typval_T *rettv);
740 static void f_setloclist(typval_T *argvars, typval_T *rettv);
741 static void f_setmatches(typval_T *argvars, typval_T *rettv);
742 static void f_setpos(typval_T *argvars, typval_T *rettv);
743 static void f_setqflist(typval_T *argvars, typval_T *rettv);
744 static void f_setreg(typval_T *argvars, typval_T *rettv);
745 static void f_settabvar(typval_T *argvars, typval_T *rettv);
746 static void f_settabwinvar(typval_T *argvars, typval_T *rettv);
747 static void f_setwinvar(typval_T *argvars, typval_T *rettv);
748 #ifdef FEAT_CRYPT
749 static void f_sha256(typval_T *argvars, typval_T *rettv);
750 #endif /* FEAT_CRYPT */
751 static void f_shellescape(typval_T *argvars, typval_T *rettv);
752 static void f_shiftwidth(typval_T *argvars, typval_T *rettv);
753 static void f_simplify(typval_T *argvars, typval_T *rettv);
754 #ifdef FEAT_FLOAT
755 static void f_sin(typval_T *argvars, typval_T *rettv);
756 static void f_sinh(typval_T *argvars, typval_T *rettv);
757 #endif
758 static void f_sort(typval_T *argvars, typval_T *rettv);
759 static void f_soundfold(typval_T *argvars, typval_T *rettv);
760 static void f_spellbadword(typval_T *argvars, typval_T *rettv);
761 static void f_spellsuggest(typval_T *argvars, typval_T *rettv);
762 static void f_split(typval_T *argvars, typval_T *rettv);
763 #ifdef FEAT_FLOAT
764 static void f_sqrt(typval_T *argvars, typval_T *rettv);
765 static void f_str2float(typval_T *argvars, typval_T *rettv);
766 #endif
767 static void f_str2nr(typval_T *argvars, typval_T *rettv);
768 static void f_strchars(typval_T *argvars, typval_T *rettv);
769 #ifdef HAVE_STRFTIME
770 static void f_strftime(typval_T *argvars, typval_T *rettv);
771 #endif
772 static void f_stridx(typval_T *argvars, typval_T *rettv);
773 static void f_string(typval_T *argvars, typval_T *rettv);
774 static void f_strlen(typval_T *argvars, typval_T *rettv);
775 static void f_strpart(typval_T *argvars, typval_T *rettv);
776 static void f_strridx(typval_T *argvars, typval_T *rettv);
777 static void f_strtrans(typval_T *argvars, typval_T *rettv);
778 static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv);
779 static void f_strwidth(typval_T *argvars, typval_T *rettv);
780 static void f_submatch(typval_T *argvars, typval_T *rettv);
781 static void f_substitute(typval_T *argvars, typval_T *rettv);
782 static void f_synID(typval_T *argvars, typval_T *rettv);
783 static void f_synIDattr(typval_T *argvars, typval_T *rettv);
784 static void f_synIDtrans(typval_T *argvars, typval_T *rettv);
785 static void f_synstack(typval_T *argvars, typval_T *rettv);
786 static void f_synconcealed(typval_T *argvars, typval_T *rettv);
787 static void f_system(typval_T *argvars, typval_T *rettv);
788 static void f_systemlist(typval_T *argvars, typval_T *rettv);
789 static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv);
790 static void f_tabpagenr(typval_T *argvars, typval_T *rettv);
791 static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv);
792 static void f_taglist(typval_T *argvars, typval_T *rettv);
793 static void f_tagfiles(typval_T *argvars, typval_T *rettv);
794 static void f_tempname(typval_T *argvars, typval_T *rettv);
795 static void f_test(typval_T *argvars, typval_T *rettv);
796 #ifdef FEAT_FLOAT
797 static void f_tan(typval_T *argvars, typval_T *rettv);
798 static void f_tanh(typval_T *argvars, typval_T *rettv);
799 #endif
800 #ifdef FEAT_TIMERS
801 static void f_timer_start(typval_T *argvars, typval_T *rettv);
802 static void f_timer_stop(typval_T *argvars, typval_T *rettv);
803 #endif
804 static void f_tolower(typval_T *argvars, typval_T *rettv);
805 static void f_toupper(typval_T *argvars, typval_T *rettv);
806 static void f_tr(typval_T *argvars, typval_T *rettv);
807 #ifdef FEAT_FLOAT
808 static void f_trunc(typval_T *argvars, typval_T *rettv);
809 #endif
810 static void f_type(typval_T *argvars, typval_T *rettv);
811 static void f_undofile(typval_T *argvars, typval_T *rettv);
812 static void f_undotree(typval_T *argvars, typval_T *rettv);
813 static void f_uniq(typval_T *argvars, typval_T *rettv);
814 static void f_values(typval_T *argvars, typval_T *rettv);
815 static void f_virtcol(typval_T *argvars, typval_T *rettv);
816 static void f_visualmode(typval_T *argvars, typval_T *rettv);
817 static void f_wildmenumode(typval_T *argvars, typval_T *rettv);
818 static void f_win_findbuf(typval_T *argvars, typval_T *rettv);
819 static void f_win_getid(typval_T *argvars, typval_T *rettv);
820 static void f_win_gotoid(typval_T *argvars, typval_T *rettv);
821 static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv);
822 static void f_win_id2win(typval_T *argvars, typval_T *rettv);
823 static void f_winbufnr(typval_T *argvars, typval_T *rettv);
824 static void f_wincol(typval_T *argvars, typval_T *rettv);
825 static void f_winheight(typval_T *argvars, typval_T *rettv);
826 static void f_winline(typval_T *argvars, typval_T *rettv);
827 static void f_winnr(typval_T *argvars, typval_T *rettv);
828 static void f_winrestcmd(typval_T *argvars, typval_T *rettv);
829 static void f_winrestview(typval_T *argvars, typval_T *rettv);
830 static void f_winsaveview(typval_T *argvars, typval_T *rettv);
831 static void f_winwidth(typval_T *argvars, typval_T *rettv);
832 static void f_writefile(typval_T *argvars, typval_T *rettv);
833 static void f_wordcount(typval_T *argvars, typval_T *rettv);
834 static void f_xor(typval_T *argvars, typval_T *rettv);
835 
836 static int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp);
837 static pos_T *var2fpos(typval_T *varp, int dollar_lnum, int *fnum);
838 static int get_env_len(char_u **arg);
839 static int get_id_len(char_u **arg);
840 static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose);
841 static char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int flags);
842 #define FNE_INCL_BR	1	/* find_name_end(): include [] in name */
843 #define FNE_CHECK_START	2	/* find_name_end(): check name starts with
844 				   valid character */
845 static char_u * make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end);
846 static int eval_isnamec(int c);
847 static int eval_isnamec1(int c);
848 static int get_var_tv(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, int no_autoload);
849 static int handle_subscript(char_u **arg, typval_T *rettv, int evaluate, int verbose);
850 static typval_T *alloc_string_tv(char_u *string);
851 static void init_tv(typval_T *varp);
852 #ifdef FEAT_FLOAT
853 static float_T get_tv_float(typval_T *varp);
854 #endif
855 static linenr_T get_tv_lnum(typval_T *argvars);
856 static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf);
857 static dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
858 static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
859 static hashtab_T *find_var_ht(char_u *name, char_u **varname);
860 static funccall_T *get_funccal(void);
861 static void vars_clear_ext(hashtab_T *ht, int free_val);
862 static void delete_var(hashtab_T *ht, hashitem_T *hi);
863 static void list_one_var(dictitem_T *v, char_u *prefix, int *first);
864 static void list_one_var_a(char_u *prefix, char_u *name, int type, char_u *string, int *first);
865 static void set_var(char_u *name, typval_T *varp, int copy);
866 static int var_check_ro(int flags, char_u *name, int use_gettext);
867 static int var_check_fixed(int flags, char_u *name, int use_gettext);
868 static int var_check_func_name(char_u *name, int new_var);
869 static int valid_varname(char_u *varname);
870 static int tv_check_lock(int lock, char_u *name, int use_gettext);
871 static int item_copy(typval_T *from, typval_T *to, int deep, int copyID);
872 static char_u *find_option_end(char_u **arg, int *opt_flags);
873 static char_u *trans_function_name(char_u **pp, int skip, int flags, funcdict_T *fd, partial_T **partial);
874 static int eval_fname_script(char_u *p);
875 static int eval_fname_sid(char_u *p);
876 static void list_func_head(ufunc_T *fp, int indent);
877 static ufunc_T *find_func(char_u *name);
878 static int function_exists(char_u *name);
879 static int builtin_function(char_u *name, int len);
880 #ifdef FEAT_PROFILE
881 static void func_do_profile(ufunc_T *fp);
882 static void prof_sort_list(FILE *fd, ufunc_T **sorttab, int st_len, char *title, int prefer_self);
883 static void prof_func_line(FILE *fd, int count, proftime_T *total, proftime_T *self, int prefer_self);
884 static int
885 # ifdef __BORLANDC__
886     _RTLENTRYF
887 # endif
888 	prof_total_cmp(const void *s1, const void *s2);
889 static int
890 # ifdef __BORLANDC__
891     _RTLENTRYF
892 # endif
893 	prof_self_cmp(const void *s1, const void *s2);
894 #endif
895 static int script_autoload(char_u *name, int reload);
896 static char_u *autoload_name(char_u *name);
897 static void cat_func_name(char_u *buf, ufunc_T *fp);
898 static void func_free(ufunc_T *fp);
899 static void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict);
900 static int can_free_funccal(funccall_T *fc, int copyID) ;
901 static void free_funccal(funccall_T *fc, int free_val);
902 static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr);
903 static win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp);
904 static win_T *find_tabwin(typval_T *wvp, typval_T *tvp);
905 static void getwinvar(typval_T *argvars, typval_T *rettv, int off);
906 static int searchpair_cmn(typval_T *argvars, pos_T *match_pos);
907 static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp);
908 static void setwinvar(typval_T *argvars, typval_T *rettv, int off);
909 static int write_list(FILE *fd, list_T *list, int binary);
910 static void get_cmd_output_as_rettv(typval_T *argvars, typval_T *rettv, int retlist);
911 
912 
913 #ifdef EBCDIC
914 static int compare_func_name(const void *s1, const void *s2);
915 static void sortFunctions();
916 #endif
917 
918 /*
919  * Initialize the global and v: variables.
920  */
921     void
922 eval_init(void)
923 {
924     int		    i;
925     struct vimvar   *p;
926 
927     init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE);
928     init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE);
929     vimvardict.dv_lock = VAR_FIXED;
930     hash_init(&compat_hashtab);
931     hash_init(&func_hashtab);
932 
933     for (i = 0; i < VV_LEN; ++i)
934     {
935 	p = &vimvars[i];
936 	STRCPY(p->vv_di.di_key, p->vv_name);
937 	if (p->vv_flags & VV_RO)
938 	    p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
939 	else if (p->vv_flags & VV_RO_SBX)
940 	    p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX;
941 	else
942 	    p->vv_di.di_flags = DI_FLAGS_FIX;
943 
944 	/* add to v: scope dict, unless the value is not always available */
945 	if (p->vv_type != VAR_UNKNOWN)
946 	    hash_add(&vimvarht, p->vv_di.di_key);
947 	if (p->vv_flags & VV_COMPAT)
948 	    /* add to compat scope dict */
949 	    hash_add(&compat_hashtab, p->vv_di.di_key);
950     }
951     vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
952 
953     set_vim_var_nr(VV_SEARCHFORWARD, 1L);
954     set_vim_var_nr(VV_HLSEARCH, 1L);
955     set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
956     set_vim_var_list(VV_ERRORS, list_alloc());
957 
958     set_vim_var_nr(VV_FALSE, VVAL_FALSE);
959     set_vim_var_nr(VV_TRUE, VVAL_TRUE);
960     set_vim_var_nr(VV_NONE, VVAL_NONE);
961     set_vim_var_nr(VV_NULL, VVAL_NULL);
962 
963     set_reg_var(0);  /* default for v:register is not 0 but '"' */
964 
965 #ifdef EBCDIC
966     /*
967      * Sort the function table, to enable binary search.
968      */
969     sortFunctions();
970 #endif
971 }
972 
973 #if defined(EXITFREE) || defined(PROTO)
974     void
975 eval_clear(void)
976 {
977     int		    i;
978     struct vimvar   *p;
979 
980     for (i = 0; i < VV_LEN; ++i)
981     {
982 	p = &vimvars[i];
983 	if (p->vv_di.di_tv.v_type == VAR_STRING)
984 	{
985 	    vim_free(p->vv_str);
986 	    p->vv_str = NULL;
987 	}
988 	else if (p->vv_di.di_tv.v_type == VAR_LIST)
989 	{
990 	    list_unref(p->vv_list);
991 	    p->vv_list = NULL;
992 	}
993     }
994     hash_clear(&vimvarht);
995     hash_init(&vimvarht);  /* garbage_collect() will access it */
996     hash_clear(&compat_hashtab);
997 
998     free_scriptnames();
999 # if defined(FEAT_CMDL_COMPL)
1000     free_locales();
1001 # endif
1002 
1003     /* global variables */
1004     vars_clear(&globvarht);
1005 
1006     /* autoloaded script names */
1007     ga_clear_strings(&ga_loaded);
1008 
1009     /* Script-local variables. First clear all the variables and in a second
1010      * loop free the scriptvar_T, because a variable in one script might hold
1011      * a reference to the whole scope of another script. */
1012     for (i = 1; i <= ga_scripts.ga_len; ++i)
1013 	vars_clear(&SCRIPT_VARS(i));
1014     for (i = 1; i <= ga_scripts.ga_len; ++i)
1015 	vim_free(SCRIPT_SV(i));
1016     ga_clear(&ga_scripts);
1017 
1018     /* unreferenced lists and dicts */
1019     (void)garbage_collect();
1020 
1021     /* functions */
1022     free_all_functions();
1023     hash_clear(&func_hashtab);
1024 }
1025 #endif
1026 
1027 /*
1028  * Return the name of the executed function.
1029  */
1030     char_u *
1031 func_name(void *cookie)
1032 {
1033     return ((funccall_T *)cookie)->func->uf_name;
1034 }
1035 
1036 /*
1037  * Return the address holding the next breakpoint line for a funccall cookie.
1038  */
1039     linenr_T *
1040 func_breakpoint(void *cookie)
1041 {
1042     return &((funccall_T *)cookie)->breakpoint;
1043 }
1044 
1045 /*
1046  * Return the address holding the debug tick for a funccall cookie.
1047  */
1048     int *
1049 func_dbg_tick(void *cookie)
1050 {
1051     return &((funccall_T *)cookie)->dbg_tick;
1052 }
1053 
1054 /*
1055  * Return the nesting level for a funccall cookie.
1056  */
1057     int
1058 func_level(void *cookie)
1059 {
1060     return ((funccall_T *)cookie)->level;
1061 }
1062 
1063 /* pointer to funccal for currently active function */
1064 funccall_T *current_funccal = NULL;
1065 
1066 /* pointer to list of previously used funccal, still around because some
1067  * item in it is still being used. */
1068 funccall_T *previous_funccal = NULL;
1069 
1070 /*
1071  * Return TRUE when a function was ended by a ":return" command.
1072  */
1073     int
1074 current_func_returned(void)
1075 {
1076     return current_funccal->returned;
1077 }
1078 
1079 
1080 /*
1081  * Set an internal variable to a string value. Creates the variable if it does
1082  * not already exist.
1083  */
1084     void
1085 set_internal_string_var(char_u *name, char_u *value)
1086 {
1087     char_u	*val;
1088     typval_T	*tvp;
1089 
1090     val = vim_strsave(value);
1091     if (val != NULL)
1092     {
1093 	tvp = alloc_string_tv(val);
1094 	if (tvp != NULL)
1095 	{
1096 	    set_var(name, tvp, FALSE);
1097 	    free_tv(tvp);
1098 	}
1099     }
1100 }
1101 
1102 static lval_T	*redir_lval = NULL;
1103 static garray_T redir_ga;	/* only valid when redir_lval is not NULL */
1104 static char_u	*redir_endp = NULL;
1105 static char_u	*redir_varname = NULL;
1106 
1107 /*
1108  * Start recording command output to a variable
1109  * When "append" is TRUE append to an existing variable.
1110  * Returns OK if successfully completed the setup.  FAIL otherwise.
1111  */
1112     int
1113 var_redir_start(char_u *name, int append)
1114 {
1115     int		save_emsg;
1116     int		err;
1117     typval_T	tv;
1118 
1119     /* Catch a bad name early. */
1120     if (!eval_isnamec1(*name))
1121     {
1122 	EMSG(_(e_invarg));
1123 	return FAIL;
1124     }
1125 
1126     /* Make a copy of the name, it is used in redir_lval until redir ends. */
1127     redir_varname = vim_strsave(name);
1128     if (redir_varname == NULL)
1129 	return FAIL;
1130 
1131     redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T));
1132     if (redir_lval == NULL)
1133     {
1134 	var_redir_stop();
1135 	return FAIL;
1136     }
1137 
1138     /* The output is stored in growarray "redir_ga" until redirection ends. */
1139     ga_init2(&redir_ga, (int)sizeof(char), 500);
1140 
1141     /* Parse the variable name (can be a dict or list entry). */
1142     redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
1143 							     FNE_CHECK_START);
1144     if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
1145     {
1146 	clear_lval(redir_lval);
1147 	if (redir_endp != NULL && *redir_endp != NUL)
1148 	    /* Trailing characters are present after the variable name */
1149 	    EMSG(_(e_trailing));
1150 	else
1151 	    EMSG(_(e_invarg));
1152 	redir_endp = NULL;  /* don't store a value, only cleanup */
1153 	var_redir_stop();
1154 	return FAIL;
1155     }
1156 
1157     /* check if we can write to the variable: set it to or append an empty
1158      * string */
1159     save_emsg = did_emsg;
1160     did_emsg = FALSE;
1161     tv.v_type = VAR_STRING;
1162     tv.vval.v_string = (char_u *)"";
1163     if (append)
1164 	set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)".");
1165     else
1166 	set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"=");
1167     clear_lval(redir_lval);
1168     err = did_emsg;
1169     did_emsg |= save_emsg;
1170     if (err)
1171     {
1172 	redir_endp = NULL;  /* don't store a value, only cleanup */
1173 	var_redir_stop();
1174 	return FAIL;
1175     }
1176 
1177     return OK;
1178 }
1179 
1180 /*
1181  * Append "value[value_len]" to the variable set by var_redir_start().
1182  * The actual appending is postponed until redirection ends, because the value
1183  * appended may in fact be the string we write to, changing it may cause freed
1184  * memory to be used:
1185  *   :redir => foo
1186  *   :let foo
1187  *   :redir END
1188  */
1189     void
1190 var_redir_str(char_u *value, int value_len)
1191 {
1192     int		len;
1193 
1194     if (redir_lval == NULL)
1195 	return;
1196 
1197     if (value_len == -1)
1198 	len = (int)STRLEN(value);	/* Append the entire string */
1199     else
1200 	len = value_len;		/* Append only "value_len" characters */
1201 
1202     if (ga_grow(&redir_ga, len) == OK)
1203     {
1204 	mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
1205 	redir_ga.ga_len += len;
1206     }
1207     else
1208 	var_redir_stop();
1209 }
1210 
1211 /*
1212  * Stop redirecting command output to a variable.
1213  * Frees the allocated memory.
1214  */
1215     void
1216 var_redir_stop(void)
1217 {
1218     typval_T	tv;
1219 
1220     if (redir_lval != NULL)
1221     {
1222 	/* If there was no error: assign the text to the variable. */
1223 	if (redir_endp != NULL)
1224 	{
1225 	    ga_append(&redir_ga, NUL);  /* Append the trailing NUL. */
1226 	    tv.v_type = VAR_STRING;
1227 	    tv.vval.v_string = redir_ga.ga_data;
1228 	    /* Call get_lval() again, if it's inside a Dict or List it may
1229 	     * have changed. */
1230 	    redir_endp = get_lval(redir_varname, NULL, redir_lval,
1231 					FALSE, FALSE, 0, FNE_CHECK_START);
1232 	    if (redir_endp != NULL && redir_lval->ll_name != NULL)
1233 		set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
1234 	    clear_lval(redir_lval);
1235 	}
1236 
1237 	/* free the collected output */
1238 	vim_free(redir_ga.ga_data);
1239 	redir_ga.ga_data = NULL;
1240 
1241 	vim_free(redir_lval);
1242 	redir_lval = NULL;
1243     }
1244     vim_free(redir_varname);
1245     redir_varname = NULL;
1246 }
1247 
1248 # if defined(FEAT_MBYTE) || defined(PROTO)
1249     int
1250 eval_charconvert(
1251     char_u	*enc_from,
1252     char_u	*enc_to,
1253     char_u	*fname_from,
1254     char_u	*fname_to)
1255 {
1256     int		err = FALSE;
1257 
1258     set_vim_var_string(VV_CC_FROM, enc_from, -1);
1259     set_vim_var_string(VV_CC_TO, enc_to, -1);
1260     set_vim_var_string(VV_FNAME_IN, fname_from, -1);
1261     set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
1262     if (eval_to_bool(p_ccv, &err, NULL, FALSE))
1263 	err = TRUE;
1264     set_vim_var_string(VV_CC_FROM, NULL, -1);
1265     set_vim_var_string(VV_CC_TO, NULL, -1);
1266     set_vim_var_string(VV_FNAME_IN, NULL, -1);
1267     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
1268 
1269     if (err)
1270 	return FAIL;
1271     return OK;
1272 }
1273 # endif
1274 
1275 # if defined(FEAT_POSTSCRIPT) || defined(PROTO)
1276     int
1277 eval_printexpr(char_u *fname, char_u *args)
1278 {
1279     int		err = FALSE;
1280 
1281     set_vim_var_string(VV_FNAME_IN, fname, -1);
1282     set_vim_var_string(VV_CMDARG, args, -1);
1283     if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
1284 	err = TRUE;
1285     set_vim_var_string(VV_FNAME_IN, NULL, -1);
1286     set_vim_var_string(VV_CMDARG, NULL, -1);
1287 
1288     if (err)
1289     {
1290 	mch_remove(fname);
1291 	return FAIL;
1292     }
1293     return OK;
1294 }
1295 # endif
1296 
1297 # if defined(FEAT_DIFF) || defined(PROTO)
1298     void
1299 eval_diff(
1300     char_u	*origfile,
1301     char_u	*newfile,
1302     char_u	*outfile)
1303 {
1304     int		err = FALSE;
1305 
1306     set_vim_var_string(VV_FNAME_IN, origfile, -1);
1307     set_vim_var_string(VV_FNAME_NEW, newfile, -1);
1308     set_vim_var_string(VV_FNAME_OUT, outfile, -1);
1309     (void)eval_to_bool(p_dex, &err, NULL, FALSE);
1310     set_vim_var_string(VV_FNAME_IN, NULL, -1);
1311     set_vim_var_string(VV_FNAME_NEW, NULL, -1);
1312     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
1313 }
1314 
1315     void
1316 eval_patch(
1317     char_u	*origfile,
1318     char_u	*difffile,
1319     char_u	*outfile)
1320 {
1321     int		err;
1322 
1323     set_vim_var_string(VV_FNAME_IN, origfile, -1);
1324     set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
1325     set_vim_var_string(VV_FNAME_OUT, outfile, -1);
1326     (void)eval_to_bool(p_pex, &err, NULL, FALSE);
1327     set_vim_var_string(VV_FNAME_IN, NULL, -1);
1328     set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
1329     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
1330 }
1331 # endif
1332 
1333 /*
1334  * Top level evaluation function, returning a boolean.
1335  * Sets "error" to TRUE if there was an error.
1336  * Return TRUE or FALSE.
1337  */
1338     int
1339 eval_to_bool(
1340     char_u	*arg,
1341     int		*error,
1342     char_u	**nextcmd,
1343     int		skip)	    /* only parse, don't execute */
1344 {
1345     typval_T	tv;
1346     int		retval = FALSE;
1347 
1348     if (skip)
1349 	++emsg_skip;
1350     if (eval0(arg, &tv, nextcmd, !skip) == FAIL)
1351 	*error = TRUE;
1352     else
1353     {
1354 	*error = FALSE;
1355 	if (!skip)
1356 	{
1357 	    retval = (get_tv_number_chk(&tv, error) != 0);
1358 	    clear_tv(&tv);
1359 	}
1360     }
1361     if (skip)
1362 	--emsg_skip;
1363 
1364     return retval;
1365 }
1366 
1367 /*
1368  * Top level evaluation function, returning a string.  If "skip" is TRUE,
1369  * only parsing to "nextcmd" is done, without reporting errors.  Return
1370  * pointer to allocated memory, or NULL for failure or when "skip" is TRUE.
1371  */
1372     char_u *
1373 eval_to_string_skip(
1374     char_u	*arg,
1375     char_u	**nextcmd,
1376     int		skip)	    /* only parse, don't execute */
1377 {
1378     typval_T	tv;
1379     char_u	*retval;
1380 
1381     if (skip)
1382 	++emsg_skip;
1383     if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip)
1384 	retval = NULL;
1385     else
1386     {
1387 	retval = vim_strsave(get_tv_string(&tv));
1388 	clear_tv(&tv);
1389     }
1390     if (skip)
1391 	--emsg_skip;
1392 
1393     return retval;
1394 }
1395 
1396 /*
1397  * Skip over an expression at "*pp".
1398  * Return FAIL for an error, OK otherwise.
1399  */
1400     int
1401 skip_expr(char_u **pp)
1402 {
1403     typval_T	rettv;
1404 
1405     *pp = skipwhite(*pp);
1406     return eval1(pp, &rettv, FALSE);
1407 }
1408 
1409 /*
1410  * Top level evaluation function, returning a string.
1411  * When "convert" is TRUE convert a List into a sequence of lines and convert
1412  * a Float to a String.
1413  * Return pointer to allocated memory, or NULL for failure.
1414  */
1415     char_u *
1416 eval_to_string(
1417     char_u	*arg,
1418     char_u	**nextcmd,
1419     int		convert)
1420 {
1421     typval_T	tv;
1422     char_u	*retval;
1423     garray_T	ga;
1424 #ifdef FEAT_FLOAT
1425     char_u	numbuf[NUMBUFLEN];
1426 #endif
1427 
1428     if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
1429 	retval = NULL;
1430     else
1431     {
1432 	if (convert && tv.v_type == VAR_LIST)
1433 	{
1434 	    ga_init2(&ga, (int)sizeof(char), 80);
1435 	    if (tv.vval.v_list != NULL)
1436 	    {
1437 		list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0);
1438 		if (tv.vval.v_list->lv_len > 0)
1439 		    ga_append(&ga, NL);
1440 	    }
1441 	    ga_append(&ga, NUL);
1442 	    retval = (char_u *)ga.ga_data;
1443 	}
1444 #ifdef FEAT_FLOAT
1445 	else if (convert && tv.v_type == VAR_FLOAT)
1446 	{
1447 	    vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
1448 	    retval = vim_strsave(numbuf);
1449 	}
1450 #endif
1451 	else
1452 	    retval = vim_strsave(get_tv_string(&tv));
1453 	clear_tv(&tv);
1454     }
1455 
1456     return retval;
1457 }
1458 
1459 /*
1460  * Call eval_to_string() without using current local variables and using
1461  * textlock.  When "use_sandbox" is TRUE use the sandbox.
1462  */
1463     char_u *
1464 eval_to_string_safe(
1465     char_u	*arg,
1466     char_u	**nextcmd,
1467     int		use_sandbox)
1468 {
1469     char_u	*retval;
1470     void	*save_funccalp;
1471 
1472     save_funccalp = save_funccal();
1473     if (use_sandbox)
1474 	++sandbox;
1475     ++textlock;
1476     retval = eval_to_string(arg, nextcmd, FALSE);
1477     if (use_sandbox)
1478 	--sandbox;
1479     --textlock;
1480     restore_funccal(save_funccalp);
1481     return retval;
1482 }
1483 
1484 /*
1485  * Top level evaluation function, returning a number.
1486  * Evaluates "expr" silently.
1487  * Returns -1 for an error.
1488  */
1489     int
1490 eval_to_number(char_u *expr)
1491 {
1492     typval_T	rettv;
1493     int		retval;
1494     char_u	*p = skipwhite(expr);
1495 
1496     ++emsg_off;
1497 
1498     if (eval1(&p, &rettv, TRUE) == FAIL)
1499 	retval = -1;
1500     else
1501     {
1502 	retval = get_tv_number_chk(&rettv, NULL);
1503 	clear_tv(&rettv);
1504     }
1505     --emsg_off;
1506 
1507     return retval;
1508 }
1509 
1510 /*
1511  * Prepare v: variable "idx" to be used.
1512  * Save the current typeval in "save_tv".
1513  * When not used yet add the variable to the v: hashtable.
1514  */
1515     static void
1516 prepare_vimvar(int idx, typval_T *save_tv)
1517 {
1518     *save_tv = vimvars[idx].vv_tv;
1519     if (vimvars[idx].vv_type == VAR_UNKNOWN)
1520 	hash_add(&vimvarht, vimvars[idx].vv_di.di_key);
1521 }
1522 
1523 /*
1524  * Restore v: variable "idx" to typeval "save_tv".
1525  * When no longer defined, remove the variable from the v: hashtable.
1526  */
1527     static void
1528 restore_vimvar(int idx, typval_T *save_tv)
1529 {
1530     hashitem_T	*hi;
1531 
1532     vimvars[idx].vv_tv = *save_tv;
1533     if (vimvars[idx].vv_type == VAR_UNKNOWN)
1534     {
1535 	hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
1536 	if (HASHITEM_EMPTY(hi))
1537 	    EMSG2(_(e_intern2), "restore_vimvar()");
1538 	else
1539 	    hash_remove(&vimvarht, hi);
1540     }
1541 }
1542 
1543 #if defined(FEAT_SPELL) || defined(PROTO)
1544 /*
1545  * Evaluate an expression to a list with suggestions.
1546  * For the "expr:" part of 'spellsuggest'.
1547  * Returns NULL when there is an error.
1548  */
1549     list_T *
1550 eval_spell_expr(char_u *badword, char_u *expr)
1551 {
1552     typval_T	save_val;
1553     typval_T	rettv;
1554     list_T	*list = NULL;
1555     char_u	*p = skipwhite(expr);
1556 
1557     /* Set "v:val" to the bad word. */
1558     prepare_vimvar(VV_VAL, &save_val);
1559     vimvars[VV_VAL].vv_type = VAR_STRING;
1560     vimvars[VV_VAL].vv_str = badword;
1561     if (p_verbose == 0)
1562 	++emsg_off;
1563 
1564     if (eval1(&p, &rettv, TRUE) == OK)
1565     {
1566 	if (rettv.v_type != VAR_LIST)
1567 	    clear_tv(&rettv);
1568 	else
1569 	    list = rettv.vval.v_list;
1570     }
1571 
1572     if (p_verbose == 0)
1573 	--emsg_off;
1574     restore_vimvar(VV_VAL, &save_val);
1575 
1576     return list;
1577 }
1578 
1579 /*
1580  * "list" is supposed to contain two items: a word and a number.  Return the
1581  * word in "pp" and the number as the return value.
1582  * Return -1 if anything isn't right.
1583  * Used to get the good word and score from the eval_spell_expr() result.
1584  */
1585     int
1586 get_spellword(list_T *list, char_u **pp)
1587 {
1588     listitem_T	*li;
1589 
1590     li = list->lv_first;
1591     if (li == NULL)
1592 	return -1;
1593     *pp = get_tv_string(&li->li_tv);
1594 
1595     li = li->li_next;
1596     if (li == NULL)
1597 	return -1;
1598     return get_tv_number(&li->li_tv);
1599 }
1600 #endif
1601 
1602 /*
1603  * Top level evaluation function.
1604  * Returns an allocated typval_T with the result.
1605  * Returns NULL when there is an error.
1606  */
1607     typval_T *
1608 eval_expr(char_u *arg, char_u **nextcmd)
1609 {
1610     typval_T	*tv;
1611 
1612     tv = (typval_T *)alloc(sizeof(typval_T));
1613     if (tv != NULL && eval0(arg, tv, nextcmd, TRUE) == FAIL)
1614     {
1615 	vim_free(tv);
1616 	tv = NULL;
1617     }
1618 
1619     return tv;
1620 }
1621 
1622 
1623 /*
1624  * Call some vimL function and return the result in "*rettv".
1625  * Uses argv[argc] for the function arguments.  Only Number and String
1626  * arguments are currently supported.
1627  * Returns OK or FAIL.
1628  */
1629     int
1630 call_vim_function(
1631     char_u      *func,
1632     int		argc,
1633     char_u      **argv,
1634     int		safe,		/* use the sandbox */
1635     int		str_arg_only,	/* all arguments are strings */
1636     typval_T	*rettv)
1637 {
1638     typval_T	*argvars;
1639     long	n;
1640     int		len;
1641     int		i;
1642     int		doesrange;
1643     void	*save_funccalp = NULL;
1644     int		ret;
1645 
1646     argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T)));
1647     if (argvars == NULL)
1648 	return FAIL;
1649 
1650     for (i = 0; i < argc; i++)
1651     {
1652 	/* Pass a NULL or empty argument as an empty string */
1653 	if (argv[i] == NULL || *argv[i] == NUL)
1654 	{
1655 	    argvars[i].v_type = VAR_STRING;
1656 	    argvars[i].vval.v_string = (char_u *)"";
1657 	    continue;
1658 	}
1659 
1660 	if (str_arg_only)
1661 	    len = 0;
1662 	else
1663 	    /* Recognize a number argument, the others must be strings. */
1664 	    vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0);
1665 	if (len != 0 && len == (int)STRLEN(argv[i]))
1666 	{
1667 	    argvars[i].v_type = VAR_NUMBER;
1668 	    argvars[i].vval.v_number = n;
1669 	}
1670 	else
1671 	{
1672 	    argvars[i].v_type = VAR_STRING;
1673 	    argvars[i].vval.v_string = argv[i];
1674 	}
1675     }
1676 
1677     if (safe)
1678     {
1679 	save_funccalp = save_funccal();
1680 	++sandbox;
1681     }
1682 
1683     rettv->v_type = VAR_UNKNOWN;		/* clear_tv() uses this */
1684     ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars,
1685 		    curwin->w_cursor.lnum, curwin->w_cursor.lnum,
1686 		    &doesrange, TRUE, NULL, NULL);
1687     if (safe)
1688     {
1689 	--sandbox;
1690 	restore_funccal(save_funccalp);
1691     }
1692     vim_free(argvars);
1693 
1694     if (ret == FAIL)
1695 	clear_tv(rettv);
1696 
1697     return ret;
1698 }
1699 
1700 /*
1701  * Call vimL function "func" and return the result as a number.
1702  * Returns -1 when calling the function fails.
1703  * Uses argv[argc] for the function arguments.
1704  */
1705     long
1706 call_func_retnr(
1707     char_u      *func,
1708     int		argc,
1709     char_u      **argv,
1710     int		safe)		/* use the sandbox */
1711 {
1712     typval_T	rettv;
1713     long	retval;
1714 
1715     /* All arguments are passed as strings, no conversion to number. */
1716     if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
1717 	return -1;
1718 
1719     retval = get_tv_number_chk(&rettv, NULL);
1720     clear_tv(&rettv);
1721     return retval;
1722 }
1723 
1724 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \
1725 	|| defined(FEAT_COMPL_FUNC) || defined(PROTO)
1726 
1727 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
1728 /*
1729  * Call vimL function "func" and return the result as a string.
1730  * Returns NULL when calling the function fails.
1731  * Uses argv[argc] for the function arguments.
1732  */
1733     void *
1734 call_func_retstr(
1735     char_u      *func,
1736     int		argc,
1737     char_u      **argv,
1738     int		safe)		/* use the sandbox */
1739 {
1740     typval_T	rettv;
1741     char_u	*retval;
1742 
1743     /* All arguments are passed as strings, no conversion to number. */
1744     if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
1745 	return NULL;
1746 
1747     retval = vim_strsave(get_tv_string(&rettv));
1748     clear_tv(&rettv);
1749     return retval;
1750 }
1751 # endif
1752 
1753 /*
1754  * Call vimL function "func" and return the result as a List.
1755  * Uses argv[argc] for the function arguments.
1756  * Returns NULL when there is something wrong.
1757  */
1758     void *
1759 call_func_retlist(
1760     char_u      *func,
1761     int		argc,
1762     char_u      **argv,
1763     int		safe)		/* use the sandbox */
1764 {
1765     typval_T	rettv;
1766 
1767     /* All arguments are passed as strings, no conversion to number. */
1768     if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
1769 	return NULL;
1770 
1771     if (rettv.v_type != VAR_LIST)
1772     {
1773 	clear_tv(&rettv);
1774 	return NULL;
1775     }
1776 
1777     return rettv.vval.v_list;
1778 }
1779 #endif
1780 
1781 /*
1782  * Save the current function call pointer, and set it to NULL.
1783  * Used when executing autocommands and for ":source".
1784  */
1785     void *
1786 save_funccal(void)
1787 {
1788     funccall_T *fc = current_funccal;
1789 
1790     current_funccal = NULL;
1791     return (void *)fc;
1792 }
1793 
1794     void
1795 restore_funccal(void *vfc)
1796 {
1797     funccall_T *fc = (funccall_T *)vfc;
1798 
1799     current_funccal = fc;
1800 }
1801 
1802 #if defined(FEAT_PROFILE) || defined(PROTO)
1803 /*
1804  * Prepare profiling for entering a child or something else that is not
1805  * counted for the script/function itself.
1806  * Should always be called in pair with prof_child_exit().
1807  */
1808     void
1809 prof_child_enter(
1810     proftime_T *tm)	/* place to store waittime */
1811 {
1812     funccall_T *fc = current_funccal;
1813 
1814     if (fc != NULL && fc->func->uf_profiling)
1815 	profile_start(&fc->prof_child);
1816     script_prof_save(tm);
1817 }
1818 
1819 /*
1820  * Take care of time spent in a child.
1821  * Should always be called after prof_child_enter().
1822  */
1823     void
1824 prof_child_exit(
1825     proftime_T *tm)	/* where waittime was stored */
1826 {
1827     funccall_T *fc = current_funccal;
1828 
1829     if (fc != NULL && fc->func->uf_profiling)
1830     {
1831 	profile_end(&fc->prof_child);
1832 	profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */
1833 	profile_add(&fc->func->uf_tm_children, &fc->prof_child);
1834 	profile_add(&fc->func->uf_tml_children, &fc->prof_child);
1835     }
1836     script_prof_restore(tm);
1837 }
1838 #endif
1839 
1840 
1841 #ifdef FEAT_FOLDING
1842 /*
1843  * Evaluate 'foldexpr'.  Returns the foldlevel, and any character preceding
1844  * it in "*cp".  Doesn't give error messages.
1845  */
1846     int
1847 eval_foldexpr(char_u *arg, int *cp)
1848 {
1849     typval_T	tv;
1850     int		retval;
1851     char_u	*s;
1852     int		use_sandbox = was_set_insecurely((char_u *)"foldexpr",
1853 								   OPT_LOCAL);
1854 
1855     ++emsg_off;
1856     if (use_sandbox)
1857 	++sandbox;
1858     ++textlock;
1859     *cp = NUL;
1860     if (eval0(arg, &tv, NULL, TRUE) == FAIL)
1861 	retval = 0;
1862     else
1863     {
1864 	/* If the result is a number, just return the number. */
1865 	if (tv.v_type == VAR_NUMBER)
1866 	    retval = tv.vval.v_number;
1867 	else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL)
1868 	    retval = 0;
1869 	else
1870 	{
1871 	    /* If the result is a string, check if there is a non-digit before
1872 	     * the number. */
1873 	    s = tv.vval.v_string;
1874 	    if (!VIM_ISDIGIT(*s) && *s != '-')
1875 		*cp = *s++;
1876 	    retval = atol((char *)s);
1877 	}
1878 	clear_tv(&tv);
1879     }
1880     --emsg_off;
1881     if (use_sandbox)
1882 	--sandbox;
1883     --textlock;
1884 
1885     return retval;
1886 }
1887 #endif
1888 
1889 /*
1890  * ":let"			list all variable values
1891  * ":let var1 var2"		list variable values
1892  * ":let var = expr"		assignment command.
1893  * ":let var += expr"		assignment command.
1894  * ":let var -= expr"		assignment command.
1895  * ":let var .= expr"		assignment command.
1896  * ":let [var1, var2] = expr"	unpack list.
1897  */
1898     void
1899 ex_let(exarg_T *eap)
1900 {
1901     char_u	*arg = eap->arg;
1902     char_u	*expr = NULL;
1903     typval_T	rettv;
1904     int		i;
1905     int		var_count = 0;
1906     int		semicolon = 0;
1907     char_u	op[2];
1908     char_u	*argend;
1909     int		first = TRUE;
1910 
1911     argend = skip_var_list(arg, &var_count, &semicolon);
1912     if (argend == NULL)
1913 	return;
1914     if (argend > arg && argend[-1] == '.')  /* for var.='str' */
1915 	--argend;
1916     expr = skipwhite(argend);
1917     if (*expr != '=' && !(vim_strchr((char_u *)"+-.", *expr) != NULL
1918 			  && expr[1] == '='))
1919     {
1920 	/*
1921 	 * ":let" without "=": list variables
1922 	 */
1923 	if (*arg == '[')
1924 	    EMSG(_(e_invarg));
1925 	else if (!ends_excmd(*arg))
1926 	    /* ":let var1 var2" */
1927 	    arg = list_arg_vars(eap, arg, &first);
1928 	else if (!eap->skip)
1929 	{
1930 	    /* ":let" */
1931 	    list_glob_vars(&first);
1932 	    list_buf_vars(&first);
1933 	    list_win_vars(&first);
1934 #ifdef FEAT_WINDOWS
1935 	    list_tab_vars(&first);
1936 #endif
1937 	    list_script_vars(&first);
1938 	    list_func_vars(&first);
1939 	    list_vim_vars(&first);
1940 	}
1941 	eap->nextcmd = check_nextcmd(arg);
1942     }
1943     else
1944     {
1945 	op[0] = '=';
1946 	op[1] = NUL;
1947 	if (*expr != '=')
1948 	{
1949 	    if (vim_strchr((char_u *)"+-.", *expr) != NULL)
1950 		op[0] = *expr;   /* +=, -= or .= */
1951 	    expr = skipwhite(expr + 2);
1952 	}
1953 	else
1954 	    expr = skipwhite(expr + 1);
1955 
1956 	if (eap->skip)
1957 	    ++emsg_skip;
1958 	i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
1959 	if (eap->skip)
1960 	{
1961 	    if (i != FAIL)
1962 		clear_tv(&rettv);
1963 	    --emsg_skip;
1964 	}
1965 	else if (i != FAIL)
1966 	{
1967 	    (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
1968 									  op);
1969 	    clear_tv(&rettv);
1970 	}
1971     }
1972 }
1973 
1974 /*
1975  * Assign the typevalue "tv" to the variable or variables at "arg_start".
1976  * Handles both "var" with any type and "[var, var; var]" with a list type.
1977  * When "nextchars" is not NULL it points to a string with characters that
1978  * must appear after the variable(s).  Use "+", "-" or "." for add, subtract
1979  * or concatenate.
1980  * Returns OK or FAIL;
1981  */
1982     static int
1983 ex_let_vars(
1984     char_u	*arg_start,
1985     typval_T	*tv,
1986     int		copy,		/* copy values from "tv", don't move */
1987     int		semicolon,	/* from skip_var_list() */
1988     int		var_count,	/* from skip_var_list() */
1989     char_u	*nextchars)
1990 {
1991     char_u	*arg = arg_start;
1992     list_T	*l;
1993     int		i;
1994     listitem_T	*item;
1995     typval_T	ltv;
1996 
1997     if (*arg != '[')
1998     {
1999 	/*
2000 	 * ":let var = expr" or ":for var in list"
2001 	 */
2002 	if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL)
2003 	    return FAIL;
2004 	return OK;
2005     }
2006 
2007     /*
2008      * ":let [v1, v2] = list" or ":for [v1, v2] in listlist"
2009      */
2010     if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL)
2011     {
2012 	EMSG(_(e_listreq));
2013 	return FAIL;
2014     }
2015 
2016     i = list_len(l);
2017     if (semicolon == 0 && var_count < i)
2018     {
2019 	EMSG(_("E687: Less targets than List items"));
2020 	return FAIL;
2021     }
2022     if (var_count - semicolon > i)
2023     {
2024 	EMSG(_("E688: More targets than List items"));
2025 	return FAIL;
2026     }
2027 
2028     item = l->lv_first;
2029     while (*arg != ']')
2030     {
2031 	arg = skipwhite(arg + 1);
2032 	arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars);
2033 	item = item->li_next;
2034 	if (arg == NULL)
2035 	    return FAIL;
2036 
2037 	arg = skipwhite(arg);
2038 	if (*arg == ';')
2039 	{
2040 	    /* Put the rest of the list (may be empty) in the var after ';'.
2041 	     * Create a new list for this. */
2042 	    l = list_alloc();
2043 	    if (l == NULL)
2044 		return FAIL;
2045 	    while (item != NULL)
2046 	    {
2047 		list_append_tv(l, &item->li_tv);
2048 		item = item->li_next;
2049 	    }
2050 
2051 	    ltv.v_type = VAR_LIST;
2052 	    ltv.v_lock = 0;
2053 	    ltv.vval.v_list = l;
2054 	    l->lv_refcount = 1;
2055 
2056 	    arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE,
2057 						    (char_u *)"]", nextchars);
2058 	    clear_tv(&ltv);
2059 	    if (arg == NULL)
2060 		return FAIL;
2061 	    break;
2062 	}
2063 	else if (*arg != ',' && *arg != ']')
2064 	{
2065 	    EMSG2(_(e_intern2), "ex_let_vars()");
2066 	    return FAIL;
2067 	}
2068     }
2069 
2070     return OK;
2071 }
2072 
2073 /*
2074  * Skip over assignable variable "var" or list of variables "[var, var]".
2075  * Used for ":let varvar = expr" and ":for varvar in expr".
2076  * For "[var, var]" increment "*var_count" for each variable.
2077  * for "[var, var; var]" set "semicolon".
2078  * Return NULL for an error.
2079  */
2080     static char_u *
2081 skip_var_list(
2082     char_u	*arg,
2083     int		*var_count,
2084     int		*semicolon)
2085 {
2086     char_u	*p, *s;
2087 
2088     if (*arg == '[')
2089     {
2090 	/* "[var, var]": find the matching ']'. */
2091 	p = arg;
2092 	for (;;)
2093 	{
2094 	    p = skipwhite(p + 1);	/* skip whites after '[', ';' or ',' */
2095 	    s = skip_var_one(p);
2096 	    if (s == p)
2097 	    {
2098 		EMSG2(_(e_invarg2), p);
2099 		return NULL;
2100 	    }
2101 	    ++*var_count;
2102 
2103 	    p = skipwhite(s);
2104 	    if (*p == ']')
2105 		break;
2106 	    else if (*p == ';')
2107 	    {
2108 		if (*semicolon == 1)
2109 		{
2110 		    EMSG(_("Double ; in list of variables"));
2111 		    return NULL;
2112 		}
2113 		*semicolon = 1;
2114 	    }
2115 	    else if (*p != ',')
2116 	    {
2117 		EMSG2(_(e_invarg2), p);
2118 		return NULL;
2119 	    }
2120 	}
2121 	return p + 1;
2122     }
2123     else
2124 	return skip_var_one(arg);
2125 }
2126 
2127 /*
2128  * Skip one (assignable) variable name, including @r, $VAR, &option, d.key,
2129  * l[idx].
2130  */
2131     static char_u *
2132 skip_var_one(char_u *arg)
2133 {
2134     if (*arg == '@' && arg[1] != NUL)
2135 	return arg + 2;
2136     return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
2137 				   NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
2138 }
2139 
2140 /*
2141  * List variables for hashtab "ht" with prefix "prefix".
2142  * If "empty" is TRUE also list NULL strings as empty strings.
2143  */
2144     static void
2145 list_hashtable_vars(
2146     hashtab_T	*ht,
2147     char_u	*prefix,
2148     int		empty,
2149     int		*first)
2150 {
2151     hashitem_T	*hi;
2152     dictitem_T	*di;
2153     int		todo;
2154 
2155     todo = (int)ht->ht_used;
2156     for (hi = ht->ht_array; todo > 0 && !got_int; ++hi)
2157     {
2158 	if (!HASHITEM_EMPTY(hi))
2159 	{
2160 	    --todo;
2161 	    di = HI2DI(hi);
2162 	    if (empty || di->di_tv.v_type != VAR_STRING
2163 					   || di->di_tv.vval.v_string != NULL)
2164 		list_one_var(di, prefix, first);
2165 	}
2166     }
2167 }
2168 
2169 /*
2170  * List global variables.
2171  */
2172     static void
2173 list_glob_vars(int *first)
2174 {
2175     list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
2176 }
2177 
2178 /*
2179  * List buffer variables.
2180  */
2181     static void
2182 list_buf_vars(int *first)
2183 {
2184     char_u	numbuf[NUMBUFLEN];
2185 
2186     list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
2187 								 TRUE, first);
2188 
2189     sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
2190     list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
2191 							       numbuf, first);
2192 }
2193 
2194 /*
2195  * List window variables.
2196  */
2197     static void
2198 list_win_vars(int *first)
2199 {
2200     list_hashtable_vars(&curwin->w_vars->dv_hashtab,
2201 						 (char_u *)"w:", TRUE, first);
2202 }
2203 
2204 #ifdef FEAT_WINDOWS
2205 /*
2206  * List tab page variables.
2207  */
2208     static void
2209 list_tab_vars(int *first)
2210 {
2211     list_hashtable_vars(&curtab->tp_vars->dv_hashtab,
2212 						 (char_u *)"t:", TRUE, first);
2213 }
2214 #endif
2215 
2216 /*
2217  * List Vim variables.
2218  */
2219     static void
2220 list_vim_vars(int *first)
2221 {
2222     list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
2223 }
2224 
2225 /*
2226  * List script-local variables, if there is a script.
2227  */
2228     static void
2229 list_script_vars(int *first)
2230 {
2231     if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
2232 	list_hashtable_vars(&SCRIPT_VARS(current_SID),
2233 						(char_u *)"s:", FALSE, first);
2234 }
2235 
2236 /*
2237  * List function variables, if there is a function.
2238  */
2239     static void
2240 list_func_vars(int *first)
2241 {
2242     if (current_funccal != NULL)
2243 	list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
2244 						(char_u *)"l:", FALSE, first);
2245 }
2246 
2247 /*
2248  * List variables in "arg".
2249  */
2250     static char_u *
2251 list_arg_vars(exarg_T *eap, char_u *arg, int *first)
2252 {
2253     int		error = FALSE;
2254     int		len;
2255     char_u	*name;
2256     char_u	*name_start;
2257     char_u	*arg_subsc;
2258     char_u	*tofree;
2259     typval_T    tv;
2260 
2261     while (!ends_excmd(*arg) && !got_int)
2262     {
2263 	if (error || eap->skip)
2264 	{
2265 	    arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
2266 	    if (!vim_iswhite(*arg) && !ends_excmd(*arg))
2267 	    {
2268 		emsg_severe = TRUE;
2269 		EMSG(_(e_trailing));
2270 		break;
2271 	    }
2272 	}
2273 	else
2274 	{
2275 	    /* get_name_len() takes care of expanding curly braces */
2276 	    name_start = name = arg;
2277 	    len = get_name_len(&arg, &tofree, TRUE, TRUE);
2278 	    if (len <= 0)
2279 	    {
2280 		/* This is mainly to keep test 49 working: when expanding
2281 		 * curly braces fails overrule the exception error message. */
2282 		if (len < 0 && !aborting())
2283 		{
2284 		    emsg_severe = TRUE;
2285 		    EMSG2(_(e_invarg2), arg);
2286 		    break;
2287 		}
2288 		error = TRUE;
2289 	    }
2290 	    else
2291 	    {
2292 		if (tofree != NULL)
2293 		    name = tofree;
2294 		if (get_var_tv(name, len, &tv, NULL, TRUE, FALSE) == FAIL)
2295 		    error = TRUE;
2296 		else
2297 		{
2298 		    /* handle d.key, l[idx], f(expr) */
2299 		    arg_subsc = arg;
2300 		    if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL)
2301 			error = TRUE;
2302 		    else
2303 		    {
2304 			if (arg == arg_subsc && len == 2 && name[1] == ':')
2305 			{
2306 			    switch (*name)
2307 			    {
2308 				case 'g': list_glob_vars(first); break;
2309 				case 'b': list_buf_vars(first); break;
2310 				case 'w': list_win_vars(first); break;
2311 #ifdef FEAT_WINDOWS
2312 				case 't': list_tab_vars(first); break;
2313 #endif
2314 				case 'v': list_vim_vars(first); break;
2315 				case 's': list_script_vars(first); break;
2316 				case 'l': list_func_vars(first); break;
2317 				default:
2318 					  EMSG2(_("E738: Can't list variables for %s"), name);
2319 			    }
2320 			}
2321 			else
2322 			{
2323 			    char_u	numbuf[NUMBUFLEN];
2324 			    char_u	*tf;
2325 			    int		c;
2326 			    char_u	*s;
2327 
2328 			    s = echo_string(&tv, &tf, numbuf, 0);
2329 			    c = *arg;
2330 			    *arg = NUL;
2331 			    list_one_var_a((char_u *)"",
2332 				    arg == arg_subsc ? name : name_start,
2333 				    tv.v_type,
2334 				    s == NULL ? (char_u *)"" : s,
2335 				    first);
2336 			    *arg = c;
2337 			    vim_free(tf);
2338 			}
2339 			clear_tv(&tv);
2340 		    }
2341 		}
2342 	    }
2343 
2344 	    vim_free(tofree);
2345 	}
2346 
2347 	arg = skipwhite(arg);
2348     }
2349 
2350     return arg;
2351 }
2352 
2353 /*
2354  * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value.
2355  * Returns a pointer to the char just after the var name.
2356  * Returns NULL if there is an error.
2357  */
2358     static char_u *
2359 ex_let_one(
2360     char_u	*arg,		/* points to variable name */
2361     typval_T	*tv,		/* value to assign to variable */
2362     int		copy,		/* copy value from "tv" */
2363     char_u	*endchars,	/* valid chars after variable name  or NULL */
2364     char_u	*op)		/* "+", "-", "."  or NULL*/
2365 {
2366     int		c1;
2367     char_u	*name;
2368     char_u	*p;
2369     char_u	*arg_end = NULL;
2370     int		len;
2371     int		opt_flags;
2372     char_u	*tofree = NULL;
2373 
2374     /*
2375      * ":let $VAR = expr": Set environment variable.
2376      */
2377     if (*arg == '$')
2378     {
2379 	/* Find the end of the name. */
2380 	++arg;
2381 	name = arg;
2382 	len = get_env_len(&arg);
2383 	if (len == 0)
2384 	    EMSG2(_(e_invarg2), name - 1);
2385 	else
2386 	{
2387 	    if (op != NULL && (*op == '+' || *op == '-'))
2388 		EMSG2(_(e_letwrong), op);
2389 	    else if (endchars != NULL
2390 			     && vim_strchr(endchars, *skipwhite(arg)) == NULL)
2391 		EMSG(_(e_letunexp));
2392 	    else if (!check_secure())
2393 	    {
2394 		c1 = name[len];
2395 		name[len] = NUL;
2396 		p = get_tv_string_chk(tv);
2397 		if (p != NULL && op != NULL && *op == '.')
2398 		{
2399 		    int	    mustfree = FALSE;
2400 		    char_u  *s = vim_getenv(name, &mustfree);
2401 
2402 		    if (s != NULL)
2403 		    {
2404 			p = tofree = concat_str(s, p);
2405 			if (mustfree)
2406 			    vim_free(s);
2407 		    }
2408 		}
2409 		if (p != NULL)
2410 		{
2411 		    vim_setenv(name, p);
2412 		    if (STRICMP(name, "HOME") == 0)
2413 			init_homedir();
2414 		    else if (didset_vim && STRICMP(name, "VIM") == 0)
2415 			didset_vim = FALSE;
2416 		    else if (didset_vimruntime
2417 					&& STRICMP(name, "VIMRUNTIME") == 0)
2418 			didset_vimruntime = FALSE;
2419 		    arg_end = arg;
2420 		}
2421 		name[len] = c1;
2422 		vim_free(tofree);
2423 	    }
2424 	}
2425     }
2426 
2427     /*
2428      * ":let &option = expr": Set option value.
2429      * ":let &l:option = expr": Set local option value.
2430      * ":let &g:option = expr": Set global option value.
2431      */
2432     else if (*arg == '&')
2433     {
2434 	/* Find the end of the name. */
2435 	p = find_option_end(&arg, &opt_flags);
2436 	if (p == NULL || (endchars != NULL
2437 			      && vim_strchr(endchars, *skipwhite(p)) == NULL))
2438 	    EMSG(_(e_letunexp));
2439 	else
2440 	{
2441 	    long	n;
2442 	    int		opt_type;
2443 	    long	numval;
2444 	    char_u	*stringval = NULL;
2445 	    char_u	*s;
2446 
2447 	    c1 = *p;
2448 	    *p = NUL;
2449 
2450 	    n = get_tv_number(tv);
2451 	    s = get_tv_string_chk(tv);	    /* != NULL if number or string */
2452 	    if (s != NULL && op != NULL && *op != '=')
2453 	    {
2454 		opt_type = get_option_value(arg, &numval,
2455 						       &stringval, opt_flags);
2456 		if ((opt_type == 1 && *op == '.')
2457 			|| (opt_type == 0 && *op != '.'))
2458 		    EMSG2(_(e_letwrong), op);
2459 		else
2460 		{
2461 		    if (opt_type == 1)  /* number */
2462 		    {
2463 			if (*op == '+')
2464 			    n = numval + n;
2465 			else
2466 			    n = numval - n;
2467 		    }
2468 		    else if (opt_type == 0 && stringval != NULL) /* string */
2469 		    {
2470 			s = concat_str(stringval, s);
2471 			vim_free(stringval);
2472 			stringval = s;
2473 		    }
2474 		}
2475 	    }
2476 	    if (s != NULL)
2477 	    {
2478 		set_option_value(arg, n, s, opt_flags);
2479 		arg_end = p;
2480 	    }
2481 	    *p = c1;
2482 	    vim_free(stringval);
2483 	}
2484     }
2485 
2486     /*
2487      * ":let @r = expr": Set register contents.
2488      */
2489     else if (*arg == '@')
2490     {
2491 	++arg;
2492 	if (op != NULL && (*op == '+' || *op == '-'))
2493 	    EMSG2(_(e_letwrong), op);
2494 	else if (endchars != NULL
2495 			 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL)
2496 	    EMSG(_(e_letunexp));
2497 	else
2498 	{
2499 	    char_u	*ptofree = NULL;
2500 	    char_u	*s;
2501 
2502 	    p = get_tv_string_chk(tv);
2503 	    if (p != NULL && op != NULL && *op == '.')
2504 	    {
2505 		s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC);
2506 		if (s != NULL)
2507 		{
2508 		    p = ptofree = concat_str(s, p);
2509 		    vim_free(s);
2510 		}
2511 	    }
2512 	    if (p != NULL)
2513 	    {
2514 		write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE);
2515 		arg_end = arg + 1;
2516 	    }
2517 	    vim_free(ptofree);
2518 	}
2519     }
2520 
2521     /*
2522      * ":let var = expr": Set internal variable.
2523      * ":let {expr} = expr": Idem, name made with curly braces
2524      */
2525     else if (eval_isnamec1(*arg) || *arg == '{')
2526     {
2527 	lval_T	lv;
2528 
2529 	p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START);
2530 	if (p != NULL && lv.ll_name != NULL)
2531 	{
2532 	    if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL)
2533 		EMSG(_(e_letunexp));
2534 	    else
2535 	    {
2536 		set_var_lval(&lv, p, tv, copy, op);
2537 		arg_end = p;
2538 	    }
2539 	}
2540 	clear_lval(&lv);
2541     }
2542 
2543     else
2544 	EMSG2(_(e_invarg2), arg);
2545 
2546     return arg_end;
2547 }
2548 
2549 /*
2550  * If "arg" is equal to "b:changedtick" give an error and return TRUE.
2551  */
2552     static int
2553 check_changedtick(char_u *arg)
2554 {
2555     if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13]))
2556     {
2557 	EMSG2(_(e_readonlyvar), arg);
2558 	return TRUE;
2559     }
2560     return FALSE;
2561 }
2562 
2563 /*
2564  * Get an lval: variable, Dict item or List item that can be assigned a value
2565  * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
2566  * "name.key", "name.key[expr]" etc.
2567  * Indexing only works if "name" is an existing List or Dictionary.
2568  * "name" points to the start of the name.
2569  * If "rettv" is not NULL it points to the value to be assigned.
2570  * "unlet" is TRUE for ":unlet": slightly different behavior when something is
2571  * wrong; must end in space or cmd separator.
2572  *
2573  * flags:
2574  *  GLV_QUIET:       do not give error messages
2575  *  GLV_NO_AUTOLOAD: do not use script autoloading
2576  *
2577  * Returns a pointer to just after the name, including indexes.
2578  * When an evaluation error occurs "lp->ll_name" is NULL;
2579  * Returns NULL for a parsing error.  Still need to free items in "lp"!
2580  */
2581     static char_u *
2582 get_lval(
2583     char_u	*name,
2584     typval_T	*rettv,
2585     lval_T	*lp,
2586     int		unlet,
2587     int		skip,
2588     int		flags,	    /* GLV_ values */
2589     int		fne_flags)  /* flags for find_name_end() */
2590 {
2591     char_u	*p;
2592     char_u	*expr_start, *expr_end;
2593     int		cc;
2594     dictitem_T	*v;
2595     typval_T	var1;
2596     typval_T	var2;
2597     int		empty1 = FALSE;
2598     listitem_T	*ni;
2599     char_u	*key = NULL;
2600     int		len;
2601     hashtab_T	*ht;
2602     int		quiet = flags & GLV_QUIET;
2603 
2604     /* Clear everything in "lp". */
2605     vim_memset(lp, 0, sizeof(lval_T));
2606 
2607     if (skip)
2608     {
2609 	/* When skipping just find the end of the name. */
2610 	lp->ll_name = name;
2611 	return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags);
2612     }
2613 
2614     /* Find the end of the name. */
2615     p = find_name_end(name, &expr_start, &expr_end, fne_flags);
2616     if (expr_start != NULL)
2617     {
2618 	/* Don't expand the name when we already know there is an error. */
2619 	if (unlet && !vim_iswhite(*p) && !ends_excmd(*p)
2620 						    && *p != '[' && *p != '.')
2621 	{
2622 	    EMSG(_(e_trailing));
2623 	    return NULL;
2624 	}
2625 
2626 	lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p);
2627 	if (lp->ll_exp_name == NULL)
2628 	{
2629 	    /* Report an invalid expression in braces, unless the
2630 	     * expression evaluation has been cancelled due to an
2631 	     * aborting error, an interrupt, or an exception. */
2632 	    if (!aborting() && !quiet)
2633 	    {
2634 		emsg_severe = TRUE;
2635 		EMSG2(_(e_invarg2), name);
2636 		return NULL;
2637 	    }
2638 	}
2639 	lp->ll_name = lp->ll_exp_name;
2640     }
2641     else
2642 	lp->ll_name = name;
2643 
2644     /* Without [idx] or .key we are done. */
2645     if ((*p != '[' && *p != '.') || lp->ll_name == NULL)
2646 	return p;
2647 
2648     cc = *p;
2649     *p = NUL;
2650     v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD);
2651     if (v == NULL && !quiet)
2652 	EMSG2(_(e_undefvar), lp->ll_name);
2653     *p = cc;
2654     if (v == NULL)
2655 	return NULL;
2656 
2657     /*
2658      * Loop until no more [idx] or .key is following.
2659      */
2660     lp->ll_tv = &v->di_tv;
2661     while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT))
2662     {
2663 	if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
2664 		&& !(lp->ll_tv->v_type == VAR_DICT
2665 					   && lp->ll_tv->vval.v_dict != NULL))
2666 	{
2667 	    if (!quiet)
2668 		EMSG(_("E689: Can only index a List or Dictionary"));
2669 	    return NULL;
2670 	}
2671 	if (lp->ll_range)
2672 	{
2673 	    if (!quiet)
2674 		EMSG(_("E708: [:] must come last"));
2675 	    return NULL;
2676 	}
2677 
2678 	len = -1;
2679 	if (*p == '.')
2680 	{
2681 	    key = p + 1;
2682 	    for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
2683 		;
2684 	    if (len == 0)
2685 	    {
2686 		if (!quiet)
2687 		    EMSG(_(e_emptykey));
2688 		return NULL;
2689 	    }
2690 	    p = key + len;
2691 	}
2692 	else
2693 	{
2694 	    /* Get the index [expr] or the first index [expr: ]. */
2695 	    p = skipwhite(p + 1);
2696 	    if (*p == ':')
2697 		empty1 = TRUE;
2698 	    else
2699 	    {
2700 		empty1 = FALSE;
2701 		if (eval1(&p, &var1, TRUE) == FAIL)	/* recursive! */
2702 		    return NULL;
2703 		if (get_tv_string_chk(&var1) == NULL)
2704 		{
2705 		    /* not a number or string */
2706 		    clear_tv(&var1);
2707 		    return NULL;
2708 		}
2709 	    }
2710 
2711 	    /* Optionally get the second index [ :expr]. */
2712 	    if (*p == ':')
2713 	    {
2714 		if (lp->ll_tv->v_type == VAR_DICT)
2715 		{
2716 		    if (!quiet)
2717 			EMSG(_(e_dictrange));
2718 		    if (!empty1)
2719 			clear_tv(&var1);
2720 		    return NULL;
2721 		}
2722 		if (rettv != NULL && (rettv->v_type != VAR_LIST
2723 					       || rettv->vval.v_list == NULL))
2724 		{
2725 		    if (!quiet)
2726 			EMSG(_("E709: [:] requires a List value"));
2727 		    if (!empty1)
2728 			clear_tv(&var1);
2729 		    return NULL;
2730 		}
2731 		p = skipwhite(p + 1);
2732 		if (*p == ']')
2733 		    lp->ll_empty2 = TRUE;
2734 		else
2735 		{
2736 		    lp->ll_empty2 = FALSE;
2737 		    if (eval1(&p, &var2, TRUE) == FAIL)	/* recursive! */
2738 		    {
2739 			if (!empty1)
2740 			    clear_tv(&var1);
2741 			return NULL;
2742 		    }
2743 		    if (get_tv_string_chk(&var2) == NULL)
2744 		    {
2745 			/* not a number or string */
2746 			if (!empty1)
2747 			    clear_tv(&var1);
2748 			clear_tv(&var2);
2749 			return NULL;
2750 		    }
2751 		}
2752 		lp->ll_range = TRUE;
2753 	    }
2754 	    else
2755 		lp->ll_range = FALSE;
2756 
2757 	    if (*p != ']')
2758 	    {
2759 		if (!quiet)
2760 		    EMSG(_(e_missbrac));
2761 		if (!empty1)
2762 		    clear_tv(&var1);
2763 		if (lp->ll_range && !lp->ll_empty2)
2764 		    clear_tv(&var2);
2765 		return NULL;
2766 	    }
2767 
2768 	    /* Skip to past ']'. */
2769 	    ++p;
2770 	}
2771 
2772 	if (lp->ll_tv->v_type == VAR_DICT)
2773 	{
2774 	    if (len == -1)
2775 	    {
2776 		/* "[key]": get key from "var1" */
2777 		key = get_tv_string(&var1);	/* is number or string */
2778 		if (*key == NUL)
2779 		{
2780 		    if (!quiet)
2781 			EMSG(_(e_emptykey));
2782 		    clear_tv(&var1);
2783 		    return NULL;
2784 		}
2785 	    }
2786 	    lp->ll_list = NULL;
2787 	    lp->ll_dict = lp->ll_tv->vval.v_dict;
2788 	    lp->ll_di = dict_find(lp->ll_dict, key, len);
2789 
2790 	    /* When assigning to a scope dictionary check that a function and
2791 	     * variable name is valid (only variable name unless it is l: or
2792 	     * g: dictionary). Disallow overwriting a builtin function. */
2793 	    if (rettv != NULL && lp->ll_dict->dv_scope != 0)
2794 	    {
2795 		int prevval;
2796 		int wrong;
2797 
2798 		if (len != -1)
2799 		{
2800 		    prevval = key[len];
2801 		    key[len] = NUL;
2802 		}
2803 		else
2804 		    prevval = 0; /* avoid compiler warning */
2805 		wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
2806 			       && rettv->v_type == VAR_FUNC
2807 			       && var_check_func_name(key, lp->ll_di == NULL))
2808 			|| !valid_varname(key);
2809 		if (len != -1)
2810 		    key[len] = prevval;
2811 		if (wrong)
2812 		    return NULL;
2813 	    }
2814 
2815 	    if (lp->ll_di == NULL)
2816 	    {
2817 		/* Can't add "v:" variable. */
2818 		if (lp->ll_dict == &vimvardict)
2819 		{
2820 		    EMSG2(_(e_illvar), name);
2821 		    return NULL;
2822 		}
2823 
2824 		/* Key does not exist in dict: may need to add it. */
2825 		if (*p == '[' || *p == '.' || unlet)
2826 		{
2827 		    if (!quiet)
2828 			EMSG2(_(e_dictkey), key);
2829 		    if (len == -1)
2830 			clear_tv(&var1);
2831 		    return NULL;
2832 		}
2833 		if (len == -1)
2834 		    lp->ll_newkey = vim_strsave(key);
2835 		else
2836 		    lp->ll_newkey = vim_strnsave(key, len);
2837 		if (len == -1)
2838 		    clear_tv(&var1);
2839 		if (lp->ll_newkey == NULL)
2840 		    p = NULL;
2841 		break;
2842 	    }
2843 	    /* existing variable, need to check if it can be changed */
2844 	    else if (var_check_ro(lp->ll_di->di_flags, name, FALSE))
2845 		return NULL;
2846 
2847 	    if (len == -1)
2848 		clear_tv(&var1);
2849 	    lp->ll_tv = &lp->ll_di->di_tv;
2850 	}
2851 	else
2852 	{
2853 	    /*
2854 	     * Get the number and item for the only or first index of the List.
2855 	     */
2856 	    if (empty1)
2857 		lp->ll_n1 = 0;
2858 	    else
2859 	    {
2860 		lp->ll_n1 = get_tv_number(&var1);   /* is number or string */
2861 		clear_tv(&var1);
2862 	    }
2863 	    lp->ll_dict = NULL;
2864 	    lp->ll_list = lp->ll_tv->vval.v_list;
2865 	    lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
2866 	    if (lp->ll_li == NULL)
2867 	    {
2868 		if (lp->ll_n1 < 0)
2869 		{
2870 		    lp->ll_n1 = 0;
2871 		    lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
2872 		}
2873 	    }
2874 	    if (lp->ll_li == NULL)
2875 	    {
2876 		if (lp->ll_range && !lp->ll_empty2)
2877 		    clear_tv(&var2);
2878 		if (!quiet)
2879 		    EMSGN(_(e_listidx), lp->ll_n1);
2880 		return NULL;
2881 	    }
2882 
2883 	    /*
2884 	     * May need to find the item or absolute index for the second
2885 	     * index of a range.
2886 	     * When no index given: "lp->ll_empty2" is TRUE.
2887 	     * Otherwise "lp->ll_n2" is set to the second index.
2888 	     */
2889 	    if (lp->ll_range && !lp->ll_empty2)
2890 	    {
2891 		lp->ll_n2 = get_tv_number(&var2);   /* is number or string */
2892 		clear_tv(&var2);
2893 		if (lp->ll_n2 < 0)
2894 		{
2895 		    ni = list_find(lp->ll_list, lp->ll_n2);
2896 		    if (ni == NULL)
2897 		    {
2898 			if (!quiet)
2899 			    EMSGN(_(e_listidx), lp->ll_n2);
2900 			return NULL;
2901 		    }
2902 		    lp->ll_n2 = list_idx_of_item(lp->ll_list, ni);
2903 		}
2904 
2905 		/* Check that lp->ll_n2 isn't before lp->ll_n1. */
2906 		if (lp->ll_n1 < 0)
2907 		    lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
2908 		if (lp->ll_n2 < lp->ll_n1)
2909 		{
2910 		    if (!quiet)
2911 			EMSGN(_(e_listidx), lp->ll_n2);
2912 		    return NULL;
2913 		}
2914 	    }
2915 
2916 	    lp->ll_tv = &lp->ll_li->li_tv;
2917 	}
2918     }
2919 
2920     return p;
2921 }
2922 
2923 /*
2924  * Clear lval "lp" that was filled by get_lval().
2925  */
2926     static void
2927 clear_lval(lval_T *lp)
2928 {
2929     vim_free(lp->ll_exp_name);
2930     vim_free(lp->ll_newkey);
2931 }
2932 
2933 /*
2934  * Set a variable that was parsed by get_lval() to "rettv".
2935  * "endp" points to just after the parsed name.
2936  * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=".
2937  */
2938     static void
2939 set_var_lval(
2940     lval_T	*lp,
2941     char_u	*endp,
2942     typval_T	*rettv,
2943     int		copy,
2944     char_u	*op)
2945 {
2946     int		cc;
2947     listitem_T	*ri;
2948     dictitem_T	*di;
2949 
2950     if (lp->ll_tv == NULL)
2951     {
2952 	if (!check_changedtick(lp->ll_name))
2953 	{
2954 	    cc = *endp;
2955 	    *endp = NUL;
2956 	    if (op != NULL && *op != '=')
2957 	    {
2958 		typval_T tv;
2959 
2960 		/* handle +=, -= and .= */
2961 		di = NULL;
2962 		if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
2963 						 &tv, &di, TRUE, FALSE) == OK)
2964 		{
2965 		    if ((di == NULL
2966 			   || (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
2967 			      && !tv_check_lock(di->di_tv.v_lock, lp->ll_name,
2968 								      FALSE)))
2969 			    && tv_op(&tv, rettv, op) == OK)
2970 			set_var(lp->ll_name, &tv, FALSE);
2971 		    clear_tv(&tv);
2972 		}
2973 	    }
2974 	    else
2975 		set_var(lp->ll_name, rettv, copy);
2976 	    *endp = cc;
2977 	}
2978     }
2979     else if (tv_check_lock(lp->ll_newkey == NULL
2980 		? lp->ll_tv->v_lock
2981 		: lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE))
2982 	;
2983     else if (lp->ll_range)
2984     {
2985 	listitem_T *ll_li = lp->ll_li;
2986 	int ll_n1 = lp->ll_n1;
2987 
2988 	/*
2989 	 * Check whether any of the list items is locked
2990 	 */
2991 	for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; )
2992 	{
2993 	    if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE))
2994 		return;
2995 	    ri = ri->li_next;
2996 	    if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == ll_n1))
2997 		break;
2998 	    ll_li = ll_li->li_next;
2999 	    ++ll_n1;
3000 	}
3001 
3002 	/*
3003 	 * Assign the List values to the list items.
3004 	 */
3005 	for (ri = rettv->vval.v_list->lv_first; ri != NULL; )
3006 	{
3007 	    if (op != NULL && *op != '=')
3008 		tv_op(&lp->ll_li->li_tv, &ri->li_tv, op);
3009 	    else
3010 	    {
3011 		clear_tv(&lp->ll_li->li_tv);
3012 		copy_tv(&ri->li_tv, &lp->ll_li->li_tv);
3013 	    }
3014 	    ri = ri->li_next;
3015 	    if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1))
3016 		break;
3017 	    if (lp->ll_li->li_next == NULL)
3018 	    {
3019 		/* Need to add an empty item. */
3020 		if (list_append_number(lp->ll_list, 0) == FAIL)
3021 		{
3022 		    ri = NULL;
3023 		    break;
3024 		}
3025 	    }
3026 	    lp->ll_li = lp->ll_li->li_next;
3027 	    ++lp->ll_n1;
3028 	}
3029 	if (ri != NULL)
3030 	    EMSG(_("E710: List value has more items than target"));
3031 	else if (lp->ll_empty2
3032 		? (lp->ll_li != NULL && lp->ll_li->li_next != NULL)
3033 		: lp->ll_n1 != lp->ll_n2)
3034 	    EMSG(_("E711: List value has not enough items"));
3035     }
3036     else
3037     {
3038 	/*
3039 	 * Assign to a List or Dictionary item.
3040 	 */
3041 	if (lp->ll_newkey != NULL)
3042 	{
3043 	    if (op != NULL && *op != '=')
3044 	    {
3045 		EMSG2(_(e_letwrong), op);
3046 		return;
3047 	    }
3048 
3049 	    /* Need to add an item to the Dictionary. */
3050 	    di = dictitem_alloc(lp->ll_newkey);
3051 	    if (di == NULL)
3052 		return;
3053 	    if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL)
3054 	    {
3055 		vim_free(di);
3056 		return;
3057 	    }
3058 	    lp->ll_tv = &di->di_tv;
3059 	}
3060 	else if (op != NULL && *op != '=')
3061 	{
3062 	    tv_op(lp->ll_tv, rettv, op);
3063 	    return;
3064 	}
3065 	else
3066 	    clear_tv(lp->ll_tv);
3067 
3068 	/*
3069 	 * Assign the value to the variable or list item.
3070 	 */
3071 	if (copy)
3072 	    copy_tv(rettv, lp->ll_tv);
3073 	else
3074 	{
3075 	    *lp->ll_tv = *rettv;
3076 	    lp->ll_tv->v_lock = 0;
3077 	    init_tv(rettv);
3078 	}
3079     }
3080 }
3081 
3082 /*
3083  * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2"
3084  * Returns OK or FAIL.
3085  */
3086     static int
3087 tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
3088 {
3089     long	n;
3090     char_u	numbuf[NUMBUFLEN];
3091     char_u	*s;
3092 
3093     /* Can't do anything with a Funcref, Dict, v:true on the right. */
3094     if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
3095 						&& tv2->v_type != VAR_SPECIAL)
3096     {
3097 	switch (tv1->v_type)
3098 	{
3099 	    case VAR_UNKNOWN:
3100 	    case VAR_DICT:
3101 	    case VAR_FUNC:
3102 	    case VAR_PARTIAL:
3103 	    case VAR_SPECIAL:
3104 	    case VAR_JOB:
3105 	    case VAR_CHANNEL:
3106 		break;
3107 
3108 	    case VAR_LIST:
3109 		if (*op != '+' || tv2->v_type != VAR_LIST)
3110 		    break;
3111 		/* List += List */
3112 		if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL)
3113 		    list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
3114 		return OK;
3115 
3116 	    case VAR_NUMBER:
3117 	    case VAR_STRING:
3118 		if (tv2->v_type == VAR_LIST)
3119 		    break;
3120 		if (*op == '+' || *op == '-')
3121 		{
3122 		    /* nr += nr  or  nr -= nr*/
3123 		    n = get_tv_number(tv1);
3124 #ifdef FEAT_FLOAT
3125 		    if (tv2->v_type == VAR_FLOAT)
3126 		    {
3127 			float_T f = n;
3128 
3129 			if (*op == '+')
3130 			    f += tv2->vval.v_float;
3131 			else
3132 			    f -= tv2->vval.v_float;
3133 			clear_tv(tv1);
3134 			tv1->v_type = VAR_FLOAT;
3135 			tv1->vval.v_float = f;
3136 		    }
3137 		    else
3138 #endif
3139 		    {
3140 			if (*op == '+')
3141 			    n += get_tv_number(tv2);
3142 			else
3143 			    n -= get_tv_number(tv2);
3144 			clear_tv(tv1);
3145 			tv1->v_type = VAR_NUMBER;
3146 			tv1->vval.v_number = n;
3147 		    }
3148 		}
3149 		else
3150 		{
3151 		    if (tv2->v_type == VAR_FLOAT)
3152 			break;
3153 
3154 		    /* str .= str */
3155 		    s = get_tv_string(tv1);
3156 		    s = concat_str(s, get_tv_string_buf(tv2, numbuf));
3157 		    clear_tv(tv1);
3158 		    tv1->v_type = VAR_STRING;
3159 		    tv1->vval.v_string = s;
3160 		}
3161 		return OK;
3162 
3163 	    case VAR_FLOAT:
3164 #ifdef FEAT_FLOAT
3165 		{
3166 		    float_T f;
3167 
3168 		    if (*op == '.' || (tv2->v_type != VAR_FLOAT
3169 				    && tv2->v_type != VAR_NUMBER
3170 				    && tv2->v_type != VAR_STRING))
3171 			break;
3172 		    if (tv2->v_type == VAR_FLOAT)
3173 			f = tv2->vval.v_float;
3174 		    else
3175 			f = get_tv_number(tv2);
3176 		    if (*op == '+')
3177 			tv1->vval.v_float += f;
3178 		    else
3179 			tv1->vval.v_float -= f;
3180 		}
3181 #endif
3182 		return OK;
3183 	}
3184     }
3185 
3186     EMSG2(_(e_letwrong), op);
3187     return FAIL;
3188 }
3189 
3190 /*
3191  * Add a watcher to a list.
3192  */
3193     void
3194 list_add_watch(list_T *l, listwatch_T *lw)
3195 {
3196     lw->lw_next = l->lv_watch;
3197     l->lv_watch = lw;
3198 }
3199 
3200 /*
3201  * Remove a watcher from a list.
3202  * No warning when it isn't found...
3203  */
3204     void
3205 list_rem_watch(list_T *l, listwatch_T *lwrem)
3206 {
3207     listwatch_T	*lw, **lwp;
3208 
3209     lwp = &l->lv_watch;
3210     for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
3211     {
3212 	if (lw == lwrem)
3213 	{
3214 	    *lwp = lw->lw_next;
3215 	    break;
3216 	}
3217 	lwp = &lw->lw_next;
3218     }
3219 }
3220 
3221 /*
3222  * Just before removing an item from a list: advance watchers to the next
3223  * item.
3224  */
3225     static void
3226 list_fix_watch(list_T *l, listitem_T *item)
3227 {
3228     listwatch_T	*lw;
3229 
3230     for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
3231 	if (lw->lw_item == item)
3232 	    lw->lw_item = item->li_next;
3233 }
3234 
3235 /*
3236  * Evaluate the expression used in a ":for var in expr" command.
3237  * "arg" points to "var".
3238  * Set "*errp" to TRUE for an error, FALSE otherwise;
3239  * Return a pointer that holds the info.  Null when there is an error.
3240  */
3241     void *
3242 eval_for_line(
3243     char_u	*arg,
3244     int		*errp,
3245     char_u	**nextcmdp,
3246     int		skip)
3247 {
3248     forinfo_T	*fi;
3249     char_u	*expr;
3250     typval_T	tv;
3251     list_T	*l;
3252 
3253     *errp = TRUE;	/* default: there is an error */
3254 
3255     fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T));
3256     if (fi == NULL)
3257 	return NULL;
3258 
3259     expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
3260     if (expr == NULL)
3261 	return fi;
3262 
3263     expr = skipwhite(expr);
3264     if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2]))
3265     {
3266 	EMSG(_("E690: Missing \"in\" after :for"));
3267 	return fi;
3268     }
3269 
3270     if (skip)
3271 	++emsg_skip;
3272     if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK)
3273     {
3274 	*errp = FALSE;
3275 	if (!skip)
3276 	{
3277 	    l = tv.vval.v_list;
3278 	    if (tv.v_type != VAR_LIST || l == NULL)
3279 	    {
3280 		EMSG(_(e_listreq));
3281 		clear_tv(&tv);
3282 	    }
3283 	    else
3284 	    {
3285 		/* No need to increment the refcount, it's already set for the
3286 		 * list being used in "tv". */
3287 		fi->fi_list = l;
3288 		list_add_watch(l, &fi->fi_lw);
3289 		fi->fi_lw.lw_item = l->lv_first;
3290 	    }
3291 	}
3292     }
3293     if (skip)
3294 	--emsg_skip;
3295 
3296     return fi;
3297 }
3298 
3299 /*
3300  * Use the first item in a ":for" list.  Advance to the next.
3301  * Assign the values to the variable (list).  "arg" points to the first one.
3302  * Return TRUE when a valid item was found, FALSE when at end of list or
3303  * something wrong.
3304  */
3305     int
3306 next_for_item(void *fi_void, char_u *arg)
3307 {
3308     forinfo_T	*fi = (forinfo_T *)fi_void;
3309     int		result;
3310     listitem_T	*item;
3311 
3312     item = fi->fi_lw.lw_item;
3313     if (item == NULL)
3314 	result = FALSE;
3315     else
3316     {
3317 	fi->fi_lw.lw_item = item->li_next;
3318 	result = (ex_let_vars(arg, &item->li_tv, TRUE,
3319 			      fi->fi_semicolon, fi->fi_varcount, NULL) == OK);
3320     }
3321     return result;
3322 }
3323 
3324 /*
3325  * Free the structure used to store info used by ":for".
3326  */
3327     void
3328 free_for_info(void *fi_void)
3329 {
3330     forinfo_T    *fi = (forinfo_T *)fi_void;
3331 
3332     if (fi != NULL && fi->fi_list != NULL)
3333     {
3334 	list_rem_watch(fi->fi_list, &fi->fi_lw);
3335 	list_unref(fi->fi_list);
3336     }
3337     vim_free(fi);
3338 }
3339 
3340 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
3341 
3342     void
3343 set_context_for_expression(
3344     expand_T	*xp,
3345     char_u	*arg,
3346     cmdidx_T	cmdidx)
3347 {
3348     int		got_eq = FALSE;
3349     int		c;
3350     char_u	*p;
3351 
3352     if (cmdidx == CMD_let)
3353     {
3354 	xp->xp_context = EXPAND_USER_VARS;
3355 	if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL)
3356 	{
3357 	    /* ":let var1 var2 ...": find last space. */
3358 	    for (p = arg + STRLEN(arg); p >= arg; )
3359 	    {
3360 		xp->xp_pattern = p;
3361 		mb_ptr_back(arg, p);
3362 		if (vim_iswhite(*p))
3363 		    break;
3364 	    }
3365 	    return;
3366 	}
3367     }
3368     else
3369 	xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS
3370 							  : EXPAND_EXPRESSION;
3371     while ((xp->xp_pattern = vim_strpbrk(arg,
3372 				  (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL)
3373     {
3374 	c = *xp->xp_pattern;
3375 	if (c == '&')
3376 	{
3377 	    c = xp->xp_pattern[1];
3378 	    if (c == '&')
3379 	    {
3380 		++xp->xp_pattern;
3381 		xp->xp_context = cmdidx != CMD_let || got_eq
3382 					 ? EXPAND_EXPRESSION : EXPAND_NOTHING;
3383 	    }
3384 	    else if (c != ' ')
3385 	    {
3386 		xp->xp_context = EXPAND_SETTINGS;
3387 		if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':')
3388 		    xp->xp_pattern += 2;
3389 
3390 	    }
3391 	}
3392 	else if (c == '$')
3393 	{
3394 	    /* environment variable */
3395 	    xp->xp_context = EXPAND_ENV_VARS;
3396 	}
3397 	else if (c == '=')
3398 	{
3399 	    got_eq = TRUE;
3400 	    xp->xp_context = EXPAND_EXPRESSION;
3401 	}
3402 	else if (c == '#'
3403 		&& xp->xp_context == EXPAND_EXPRESSION)
3404 	{
3405 	    /* Autoload function/variable contains '#'. */
3406 	    break;
3407 	}
3408 	else if ((c == '<' || c == '#')
3409 		&& xp->xp_context == EXPAND_FUNCTIONS
3410 		&& vim_strchr(xp->xp_pattern, '(') == NULL)
3411 	{
3412 	    /* Function name can start with "<SNR>" and contain '#'. */
3413 	    break;
3414 	}
3415 	else if (cmdidx != CMD_let || got_eq)
3416 	{
3417 	    if (c == '"')	    /* string */
3418 	    {
3419 		while ((c = *++xp->xp_pattern) != NUL && c != '"')
3420 		    if (c == '\\' && xp->xp_pattern[1] != NUL)
3421 			++xp->xp_pattern;
3422 		xp->xp_context = EXPAND_NOTHING;
3423 	    }
3424 	    else if (c == '\'')	    /* literal string */
3425 	    {
3426 		/* Trick: '' is like stopping and starting a literal string. */
3427 		while ((c = *++xp->xp_pattern) != NUL && c != '\'')
3428 		    /* skip */ ;
3429 		xp->xp_context = EXPAND_NOTHING;
3430 	    }
3431 	    else if (c == '|')
3432 	    {
3433 		if (xp->xp_pattern[1] == '|')
3434 		{
3435 		    ++xp->xp_pattern;
3436 		    xp->xp_context = EXPAND_EXPRESSION;
3437 		}
3438 		else
3439 		    xp->xp_context = EXPAND_COMMANDS;
3440 	    }
3441 	    else
3442 		xp->xp_context = EXPAND_EXPRESSION;
3443 	}
3444 	else
3445 	    /* Doesn't look like something valid, expand as an expression
3446 	     * anyway. */
3447 	    xp->xp_context = EXPAND_EXPRESSION;
3448 	arg = xp->xp_pattern;
3449 	if (*arg != NUL)
3450 	    while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
3451 		/* skip */ ;
3452     }
3453     xp->xp_pattern = arg;
3454 }
3455 
3456 #endif /* FEAT_CMDL_COMPL */
3457 
3458 /*
3459  * ":1,25call func(arg1, arg2)"	function call.
3460  */
3461     void
3462 ex_call(exarg_T *eap)
3463 {
3464     char_u	*arg = eap->arg;
3465     char_u	*startarg;
3466     char_u	*name;
3467     char_u	*tofree;
3468     int		len;
3469     typval_T	rettv;
3470     linenr_T	lnum;
3471     int		doesrange;
3472     int		failed = FALSE;
3473     funcdict_T	fudi;
3474     partial_T	*partial = NULL;
3475 
3476     if (eap->skip)
3477     {
3478 	/* trans_function_name() doesn't work well when skipping, use eval0()
3479 	 * instead to skip to any following command, e.g. for:
3480 	 *   :if 0 | call dict.foo().bar() | endif  */
3481 	++emsg_skip;
3482 	if (eval0(eap->arg, &rettv, &eap->nextcmd, FALSE) != FAIL)
3483 	    clear_tv(&rettv);
3484 	--emsg_skip;
3485 	return;
3486     }
3487 
3488     tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi, &partial);
3489     if (fudi.fd_newkey != NULL)
3490     {
3491 	/* Still need to give an error message for missing key. */
3492 	EMSG2(_(e_dictkey), fudi.fd_newkey);
3493 	vim_free(fudi.fd_newkey);
3494     }
3495     if (tofree == NULL)
3496 	return;
3497 
3498     /* Increase refcount on dictionary, it could get deleted when evaluating
3499      * the arguments. */
3500     if (fudi.fd_dict != NULL)
3501 	++fudi.fd_dict->dv_refcount;
3502 
3503     /* If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its
3504      * contents.  For VAR_PARTIAL get its partial, unless we already have one
3505      * from trans_function_name(). */
3506     len = (int)STRLEN(tofree);
3507     name = deref_func_name(tofree, &len,
3508 				    partial != NULL ? NULL : &partial, FALSE);
3509 
3510     /* Skip white space to allow ":call func ()".  Not good, but required for
3511      * backward compatibility. */
3512     startarg = skipwhite(arg);
3513     rettv.v_type = VAR_UNKNOWN;	/* clear_tv() uses this */
3514 
3515     if (*startarg != '(')
3516     {
3517 	EMSG2(_("E107: Missing parentheses: %s"), eap->arg);
3518 	goto end;
3519     }
3520 
3521     /*
3522      * When skipping, evaluate the function once, to find the end of the
3523      * arguments.
3524      * When the function takes a range, this is discovered after the first
3525      * call, and the loop is broken.
3526      */
3527     if (eap->skip)
3528     {
3529 	++emsg_skip;
3530 	lnum = eap->line2;	/* do it once, also with an invalid range */
3531     }
3532     else
3533 	lnum = eap->line1;
3534     for ( ; lnum <= eap->line2; ++lnum)
3535     {
3536 	if (!eap->skip && eap->addr_count > 0)
3537 	{
3538 	    curwin->w_cursor.lnum = lnum;
3539 	    curwin->w_cursor.col = 0;
3540 #ifdef FEAT_VIRTUALEDIT
3541 	    curwin->w_cursor.coladd = 0;
3542 #endif
3543 	}
3544 	arg = startarg;
3545 	if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg,
3546 		    eap->line1, eap->line2, &doesrange,
3547 				   !eap->skip, partial, fudi.fd_dict) == FAIL)
3548 	{
3549 	    failed = TRUE;
3550 	    break;
3551 	}
3552 
3553 	/* Handle a function returning a Funcref, Dictionary or List. */
3554 	if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL)
3555 	{
3556 	    failed = TRUE;
3557 	    break;
3558 	}
3559 
3560 	clear_tv(&rettv);
3561 	if (doesrange || eap->skip)
3562 	    break;
3563 
3564 	/* Stop when immediately aborting on error, or when an interrupt
3565 	 * occurred or an exception was thrown but not caught.
3566 	 * get_func_tv() returned OK, so that the check for trailing
3567 	 * characters below is executed. */
3568 	if (aborting())
3569 	    break;
3570     }
3571     if (eap->skip)
3572 	--emsg_skip;
3573 
3574     if (!failed)
3575     {
3576 	/* Check for trailing illegal characters and a following command. */
3577 	if (!ends_excmd(*arg))
3578 	{
3579 	    emsg_severe = TRUE;
3580 	    EMSG(_(e_trailing));
3581 	}
3582 	else
3583 	    eap->nextcmd = check_nextcmd(arg);
3584     }
3585 
3586 end:
3587     dict_unref(fudi.fd_dict);
3588     vim_free(tofree);
3589 }
3590 
3591 /*
3592  * ":unlet[!] var1 ... " command.
3593  */
3594     void
3595 ex_unlet(exarg_T *eap)
3596 {
3597     ex_unletlock(eap, eap->arg, 0);
3598 }
3599 
3600 /*
3601  * ":lockvar" and ":unlockvar" commands
3602  */
3603     void
3604 ex_lockvar(exarg_T *eap)
3605 {
3606     char_u	*arg = eap->arg;
3607     int		deep = 2;
3608 
3609     if (eap->forceit)
3610 	deep = -1;
3611     else if (vim_isdigit(*arg))
3612     {
3613 	deep = getdigits(&arg);
3614 	arg = skipwhite(arg);
3615     }
3616 
3617     ex_unletlock(eap, arg, deep);
3618 }
3619 
3620 /*
3621  * ":unlet", ":lockvar" and ":unlockvar" are quite similar.
3622  */
3623     static void
3624 ex_unletlock(
3625     exarg_T	*eap,
3626     char_u	*argstart,
3627     int		deep)
3628 {
3629     char_u	*arg = argstart;
3630     char_u	*name_end;
3631     int		error = FALSE;
3632     lval_T	lv;
3633 
3634     do
3635     {
3636 	/* Parse the name and find the end. */
3637 	name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0,
3638 							     FNE_CHECK_START);
3639 	if (lv.ll_name == NULL)
3640 	    error = TRUE;	    /* error but continue parsing */
3641 	if (name_end == NULL || (!vim_iswhite(*name_end)
3642 						   && !ends_excmd(*name_end)))
3643 	{
3644 	    if (name_end != NULL)
3645 	    {
3646 		emsg_severe = TRUE;
3647 		EMSG(_(e_trailing));
3648 	    }
3649 	    if (!(eap->skip || error))
3650 		clear_lval(&lv);
3651 	    break;
3652 	}
3653 
3654 	if (!error && !eap->skip)
3655 	{
3656 	    if (eap->cmdidx == CMD_unlet)
3657 	    {
3658 		if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL)
3659 		    error = TRUE;
3660 	    }
3661 	    else
3662 	    {
3663 		if (do_lock_var(&lv, name_end, deep,
3664 					  eap->cmdidx == CMD_lockvar) == FAIL)
3665 		    error = TRUE;
3666 	    }
3667 	}
3668 
3669 	if (!eap->skip)
3670 	    clear_lval(&lv);
3671 
3672 	arg = skipwhite(name_end);
3673     } while (!ends_excmd(*arg));
3674 
3675     eap->nextcmd = check_nextcmd(arg);
3676 }
3677 
3678     static int
3679 do_unlet_var(
3680     lval_T	*lp,
3681     char_u	*name_end,
3682     int		forceit)
3683 {
3684     int		ret = OK;
3685     int		cc;
3686 
3687     if (lp->ll_tv == NULL)
3688     {
3689 	cc = *name_end;
3690 	*name_end = NUL;
3691 
3692 	/* Normal name or expanded name. */
3693 	if (check_changedtick(lp->ll_name))
3694 	    ret = FAIL;
3695 	else if (do_unlet(lp->ll_name, forceit) == FAIL)
3696 	    ret = FAIL;
3697 	*name_end = cc;
3698     }
3699     else if ((lp->ll_list != NULL
3700 		   && tv_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE))
3701 	    || (lp->ll_dict != NULL
3702 		  && tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE)))
3703 	return FAIL;
3704     else if (lp->ll_range)
3705     {
3706 	listitem_T    *li;
3707 	listitem_T    *ll_li = lp->ll_li;
3708 	int	      ll_n1 = lp->ll_n1;
3709 
3710 	while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1))
3711 	{
3712 	    li = ll_li->li_next;
3713 	    if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE))
3714 		return FAIL;
3715 	    ll_li = li;
3716 	    ++ll_n1;
3717 	}
3718 
3719 	/* Delete a range of List items. */
3720 	while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1))
3721 	{
3722 	    li = lp->ll_li->li_next;
3723 	    listitem_remove(lp->ll_list, lp->ll_li);
3724 	    lp->ll_li = li;
3725 	    ++lp->ll_n1;
3726 	}
3727     }
3728     else
3729     {
3730 	if (lp->ll_list != NULL)
3731 	    /* unlet a List item. */
3732 	    listitem_remove(lp->ll_list, lp->ll_li);
3733 	else
3734 	    /* unlet a Dictionary item. */
3735 	    dictitem_remove(lp->ll_dict, lp->ll_di);
3736     }
3737 
3738     return ret;
3739 }
3740 
3741 /*
3742  * "unlet" a variable.  Return OK if it existed, FAIL if not.
3743  * When "forceit" is TRUE don't complain if the variable doesn't exist.
3744  */
3745     int
3746 do_unlet(char_u *name, int forceit)
3747 {
3748     hashtab_T	*ht;
3749     hashitem_T	*hi;
3750     char_u	*varname;
3751     dict_T	*d;
3752     dictitem_T	*di;
3753 
3754     ht = find_var_ht(name, &varname);
3755     if (ht != NULL && *varname != NUL)
3756     {
3757 	if (ht == &globvarht)
3758 	    d = &globvardict;
3759 	else if (current_funccal != NULL
3760 			     && ht == &current_funccal->l_vars.dv_hashtab)
3761 	    d = &current_funccal->l_vars;
3762 	else if (ht == &compat_hashtab)
3763 	    d = &vimvardict;
3764 	else
3765 	{
3766 	    di = find_var_in_ht(ht, *name, (char_u *)"", FALSE);
3767 	    d = di == NULL ? NULL : di->di_tv.vval.v_dict;
3768 	}
3769 	if (d == NULL)
3770 	{
3771 	    EMSG2(_(e_intern2), "do_unlet()");
3772 	    return FAIL;
3773 	}
3774 	hi = hash_find(ht, varname);
3775 	if (!HASHITEM_EMPTY(hi))
3776 	{
3777 	    di = HI2DI(hi);
3778 	    if (var_check_fixed(di->di_flags, name, FALSE)
3779 		    || var_check_ro(di->di_flags, name, FALSE)
3780 		    || tv_check_lock(d->dv_lock, name, FALSE))
3781 		return FAIL;
3782 
3783 	    delete_var(ht, hi);
3784 	    return OK;
3785 	}
3786     }
3787     if (forceit)
3788 	return OK;
3789     EMSG2(_("E108: No such variable: \"%s\""), name);
3790     return FAIL;
3791 }
3792 
3793 /*
3794  * Lock or unlock variable indicated by "lp".
3795  * "deep" is the levels to go (-1 for unlimited);
3796  * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar".
3797  */
3798     static int
3799 do_lock_var(
3800     lval_T	*lp,
3801     char_u	*name_end,
3802     int		deep,
3803     int		lock)
3804 {
3805     int		ret = OK;
3806     int		cc;
3807     dictitem_T	*di;
3808 
3809     if (deep == 0)	/* nothing to do */
3810 	return OK;
3811 
3812     if (lp->ll_tv == NULL)
3813     {
3814 	cc = *name_end;
3815 	*name_end = NUL;
3816 
3817 	/* Normal name or expanded name. */
3818 	if (check_changedtick(lp->ll_name))
3819 	    ret = FAIL;
3820 	else
3821 	{
3822 	    di = find_var(lp->ll_name, NULL, TRUE);
3823 	    if (di == NULL)
3824 		ret = FAIL;
3825 	    else
3826 	    {
3827 		if (lock)
3828 		    di->di_flags |= DI_FLAGS_LOCK;
3829 		else
3830 		    di->di_flags &= ~DI_FLAGS_LOCK;
3831 		item_lock(&di->di_tv, deep, lock);
3832 	    }
3833 	}
3834 	*name_end = cc;
3835     }
3836     else if (lp->ll_range)
3837     {
3838 	listitem_T    *li = lp->ll_li;
3839 
3840 	/* (un)lock a range of List items. */
3841 	while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1))
3842 	{
3843 	    item_lock(&li->li_tv, deep, lock);
3844 	    li = li->li_next;
3845 	    ++lp->ll_n1;
3846 	}
3847     }
3848     else if (lp->ll_list != NULL)
3849 	/* (un)lock a List item. */
3850 	item_lock(&lp->ll_li->li_tv, deep, lock);
3851     else
3852 	/* (un)lock a Dictionary item. */
3853 	item_lock(&lp->ll_di->di_tv, deep, lock);
3854 
3855     return ret;
3856 }
3857 
3858 /*
3859  * Lock or unlock an item.  "deep" is nr of levels to go.
3860  */
3861     static void
3862 item_lock(typval_T *tv, int deep, int lock)
3863 {
3864     static int	recurse = 0;
3865     list_T	*l;
3866     listitem_T	*li;
3867     dict_T	*d;
3868     hashitem_T	*hi;
3869     int		todo;
3870 
3871     if (recurse >= DICT_MAXNEST)
3872     {
3873 	EMSG(_("E743: variable nested too deep for (un)lock"));
3874 	return;
3875     }
3876     if (deep == 0)
3877 	return;
3878     ++recurse;
3879 
3880     /* lock/unlock the item itself */
3881     if (lock)
3882 	tv->v_lock |= VAR_LOCKED;
3883     else
3884 	tv->v_lock &= ~VAR_LOCKED;
3885 
3886     switch (tv->v_type)
3887     {
3888 	case VAR_UNKNOWN:
3889 	case VAR_NUMBER:
3890 	case VAR_STRING:
3891 	case VAR_FUNC:
3892 	case VAR_PARTIAL:
3893 	case VAR_FLOAT:
3894 	case VAR_SPECIAL:
3895 	case VAR_JOB:
3896 	case VAR_CHANNEL:
3897 	    break;
3898 
3899 	case VAR_LIST:
3900 	    if ((l = tv->vval.v_list) != NULL)
3901 	    {
3902 		if (lock)
3903 		    l->lv_lock |= VAR_LOCKED;
3904 		else
3905 		    l->lv_lock &= ~VAR_LOCKED;
3906 		if (deep < 0 || deep > 1)
3907 		    /* recursive: lock/unlock the items the List contains */
3908 		    for (li = l->lv_first; li != NULL; li = li->li_next)
3909 			item_lock(&li->li_tv, deep - 1, lock);
3910 	    }
3911 	    break;
3912 	case VAR_DICT:
3913 	    if ((d = tv->vval.v_dict) != NULL)
3914 	    {
3915 		if (lock)
3916 		    d->dv_lock |= VAR_LOCKED;
3917 		else
3918 		    d->dv_lock &= ~VAR_LOCKED;
3919 		if (deep < 0 || deep > 1)
3920 		{
3921 		    /* recursive: lock/unlock the items the List contains */
3922 		    todo = (int)d->dv_hashtab.ht_used;
3923 		    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
3924 		    {
3925 			if (!HASHITEM_EMPTY(hi))
3926 			{
3927 			    --todo;
3928 			    item_lock(&HI2DI(hi)->di_tv, deep - 1, lock);
3929 			}
3930 		    }
3931 		}
3932 	    }
3933     }
3934     --recurse;
3935 }
3936 
3937 /*
3938  * Return TRUE if typeval "tv" is locked: Either that value is locked itself
3939  * or it refers to a List or Dictionary that is locked.
3940  */
3941     static int
3942 tv_islocked(typval_T *tv)
3943 {
3944     return (tv->v_lock & VAR_LOCKED)
3945 	|| (tv->v_type == VAR_LIST
3946 		&& tv->vval.v_list != NULL
3947 		&& (tv->vval.v_list->lv_lock & VAR_LOCKED))
3948 	|| (tv->v_type == VAR_DICT
3949 		&& tv->vval.v_dict != NULL
3950 		&& (tv->vval.v_dict->dv_lock & VAR_LOCKED));
3951 }
3952 
3953 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO)
3954 /*
3955  * Delete all "menutrans_" variables.
3956  */
3957     void
3958 del_menutrans_vars(void)
3959 {
3960     hashitem_T	*hi;
3961     int		todo;
3962 
3963     hash_lock(&globvarht);
3964     todo = (int)globvarht.ht_used;
3965     for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi)
3966     {
3967 	if (!HASHITEM_EMPTY(hi))
3968 	{
3969 	    --todo;
3970 	    if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0)
3971 		delete_var(&globvarht, hi);
3972 	}
3973     }
3974     hash_unlock(&globvarht);
3975 }
3976 #endif
3977 
3978 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
3979 
3980 /*
3981  * Local string buffer for the next two functions to store a variable name
3982  * with its prefix. Allocated in cat_prefix_varname(), freed later in
3983  * get_user_var_name().
3984  */
3985 
3986 static char_u *cat_prefix_varname(int prefix, char_u *name);
3987 
3988 static char_u	*varnamebuf = NULL;
3989 static int	varnamebuflen = 0;
3990 
3991 /*
3992  * Function to concatenate a prefix and a variable name.
3993  */
3994     static char_u *
3995 cat_prefix_varname(int prefix, char_u *name)
3996 {
3997     int		len;
3998 
3999     len = (int)STRLEN(name) + 3;
4000     if (len > varnamebuflen)
4001     {
4002 	vim_free(varnamebuf);
4003 	len += 10;			/* some additional space */
4004 	varnamebuf = alloc(len);
4005 	if (varnamebuf == NULL)
4006 	{
4007 	    varnamebuflen = 0;
4008 	    return NULL;
4009 	}
4010 	varnamebuflen = len;
4011     }
4012     *varnamebuf = prefix;
4013     varnamebuf[1] = ':';
4014     STRCPY(varnamebuf + 2, name);
4015     return varnamebuf;
4016 }
4017 
4018 /*
4019  * Function given to ExpandGeneric() to obtain the list of user defined
4020  * (global/buffer/window/built-in) variable names.
4021  */
4022     char_u *
4023 get_user_var_name(expand_T *xp, int idx)
4024 {
4025     static long_u	gdone;
4026     static long_u	bdone;
4027     static long_u	wdone;
4028 #ifdef FEAT_WINDOWS
4029     static long_u	tdone;
4030 #endif
4031     static int		vidx;
4032     static hashitem_T	*hi;
4033     hashtab_T		*ht;
4034 
4035     if (idx == 0)
4036     {
4037 	gdone = bdone = wdone = vidx = 0;
4038 #ifdef FEAT_WINDOWS
4039 	tdone = 0;
4040 #endif
4041     }
4042 
4043     /* Global variables */
4044     if (gdone < globvarht.ht_used)
4045     {
4046 	if (gdone++ == 0)
4047 	    hi = globvarht.ht_array;
4048 	else
4049 	    ++hi;
4050 	while (HASHITEM_EMPTY(hi))
4051 	    ++hi;
4052 	if (STRNCMP("g:", xp->xp_pattern, 2) == 0)
4053 	    return cat_prefix_varname('g', hi->hi_key);
4054 	return hi->hi_key;
4055     }
4056 
4057     /* b: variables */
4058     ht = &curbuf->b_vars->dv_hashtab;
4059     if (bdone < ht->ht_used)
4060     {
4061 	if (bdone++ == 0)
4062 	    hi = ht->ht_array;
4063 	else
4064 	    ++hi;
4065 	while (HASHITEM_EMPTY(hi))
4066 	    ++hi;
4067 	return cat_prefix_varname('b', hi->hi_key);
4068     }
4069     if (bdone == ht->ht_used)
4070     {
4071 	++bdone;
4072 	return (char_u *)"b:changedtick";
4073     }
4074 
4075     /* w: variables */
4076     ht = &curwin->w_vars->dv_hashtab;
4077     if (wdone < ht->ht_used)
4078     {
4079 	if (wdone++ == 0)
4080 	    hi = ht->ht_array;
4081 	else
4082 	    ++hi;
4083 	while (HASHITEM_EMPTY(hi))
4084 	    ++hi;
4085 	return cat_prefix_varname('w', hi->hi_key);
4086     }
4087 
4088 #ifdef FEAT_WINDOWS
4089     /* t: variables */
4090     ht = &curtab->tp_vars->dv_hashtab;
4091     if (tdone < ht->ht_used)
4092     {
4093 	if (tdone++ == 0)
4094 	    hi = ht->ht_array;
4095 	else
4096 	    ++hi;
4097 	while (HASHITEM_EMPTY(hi))
4098 	    ++hi;
4099 	return cat_prefix_varname('t', hi->hi_key);
4100     }
4101 #endif
4102 
4103     /* v: variables */
4104     if (vidx < VV_LEN)
4105 	return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name);
4106 
4107     vim_free(varnamebuf);
4108     varnamebuf = NULL;
4109     varnamebuflen = 0;
4110     return NULL;
4111 }
4112 
4113 #endif /* FEAT_CMDL_COMPL */
4114 
4115 /*
4116  * Return TRUE if "pat" matches "text".
4117  * Does not use 'cpo' and always uses 'magic'.
4118  */
4119     static int
4120 pattern_match(char_u *pat, char_u *text, int ic)
4121 {
4122     int		matches = FALSE;
4123     char_u	*save_cpo;
4124     regmatch_T	regmatch;
4125 
4126     /* avoid 'l' flag in 'cpoptions' */
4127     save_cpo = p_cpo;
4128     p_cpo = (char_u *)"";
4129     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
4130     if (regmatch.regprog != NULL)
4131     {
4132 	regmatch.rm_ic = ic;
4133 	matches = vim_regexec_nl(&regmatch, text, (colnr_T)0);
4134 	vim_regfree(regmatch.regprog);
4135     }
4136     p_cpo = save_cpo;
4137     return matches;
4138 }
4139 
4140 /*
4141  * types for expressions.
4142  */
4143 typedef enum
4144 {
4145     TYPE_UNKNOWN = 0
4146     , TYPE_EQUAL	/* == */
4147     , TYPE_NEQUAL	/* != */
4148     , TYPE_GREATER	/* >  */
4149     , TYPE_GEQUAL	/* >= */
4150     , TYPE_SMALLER	/* <  */
4151     , TYPE_SEQUAL	/* <= */
4152     , TYPE_MATCH	/* =~ */
4153     , TYPE_NOMATCH	/* !~ */
4154 } exptype_T;
4155 
4156 /*
4157  * The "evaluate" argument: When FALSE, the argument is only parsed but not
4158  * executed.  The function may return OK, but the rettv will be of type
4159  * VAR_UNKNOWN.  The function still returns FAIL for a syntax error.
4160  */
4161 
4162 /*
4163  * Handle zero level expression.
4164  * This calls eval1() and handles error message and nextcmd.
4165  * Put the result in "rettv" when returning OK and "evaluate" is TRUE.
4166  * Note: "rettv.v_lock" is not set.
4167  * Return OK or FAIL.
4168  */
4169     static int
4170 eval0(
4171     char_u	*arg,
4172     typval_T	*rettv,
4173     char_u	**nextcmd,
4174     int		evaluate)
4175 {
4176     int		ret;
4177     char_u	*p;
4178 
4179     p = skipwhite(arg);
4180     ret = eval1(&p, rettv, evaluate);
4181     if (ret == FAIL || !ends_excmd(*p))
4182     {
4183 	if (ret != FAIL)
4184 	    clear_tv(rettv);
4185 	/*
4186 	 * Report the invalid expression unless the expression evaluation has
4187 	 * been cancelled due to an aborting error, an interrupt, or an
4188 	 * exception.
4189 	 */
4190 	if (!aborting())
4191 	    EMSG2(_(e_invexpr2), arg);
4192 	ret = FAIL;
4193     }
4194     if (nextcmd != NULL)
4195 	*nextcmd = check_nextcmd(p);
4196 
4197     return ret;
4198 }
4199 
4200 /*
4201  * Handle top level expression:
4202  *	expr2 ? expr1 : expr1
4203  *
4204  * "arg" must point to the first non-white of the expression.
4205  * "arg" is advanced to the next non-white after the recognized expression.
4206  *
4207  * Note: "rettv.v_lock" is not set.
4208  *
4209  * Return OK or FAIL.
4210  */
4211     static int
4212 eval1(char_u **arg, typval_T *rettv, int evaluate)
4213 {
4214     int		result;
4215     typval_T	var2;
4216 
4217     /*
4218      * Get the first variable.
4219      */
4220     if (eval2(arg, rettv, evaluate) == FAIL)
4221 	return FAIL;
4222 
4223     if ((*arg)[0] == '?')
4224     {
4225 	result = FALSE;
4226 	if (evaluate)
4227 	{
4228 	    int		error = FALSE;
4229 
4230 	    if (get_tv_number_chk(rettv, &error) != 0)
4231 		result = TRUE;
4232 	    clear_tv(rettv);
4233 	    if (error)
4234 		return FAIL;
4235 	}
4236 
4237 	/*
4238 	 * Get the second variable.
4239 	 */
4240 	*arg = skipwhite(*arg + 1);
4241 	if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */
4242 	    return FAIL;
4243 
4244 	/*
4245 	 * Check for the ":".
4246 	 */
4247 	if ((*arg)[0] != ':')
4248 	{
4249 	    EMSG(_("E109: Missing ':' after '?'"));
4250 	    if (evaluate && result)
4251 		clear_tv(rettv);
4252 	    return FAIL;
4253 	}
4254 
4255 	/*
4256 	 * Get the third variable.
4257 	 */
4258 	*arg = skipwhite(*arg + 1);
4259 	if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */
4260 	{
4261 	    if (evaluate && result)
4262 		clear_tv(rettv);
4263 	    return FAIL;
4264 	}
4265 	if (evaluate && !result)
4266 	    *rettv = var2;
4267     }
4268 
4269     return OK;
4270 }
4271 
4272 /*
4273  * Handle first level expression:
4274  *	expr2 || expr2 || expr2	    logical OR
4275  *
4276  * "arg" must point to the first non-white of the expression.
4277  * "arg" is advanced to the next non-white after the recognized expression.
4278  *
4279  * Return OK or FAIL.
4280  */
4281     static int
4282 eval2(char_u **arg, typval_T *rettv, int evaluate)
4283 {
4284     typval_T	var2;
4285     long	result;
4286     int		first;
4287     int		error = FALSE;
4288 
4289     /*
4290      * Get the first variable.
4291      */
4292     if (eval3(arg, rettv, evaluate) == FAIL)
4293 	return FAIL;
4294 
4295     /*
4296      * Repeat until there is no following "||".
4297      */
4298     first = TRUE;
4299     result = FALSE;
4300     while ((*arg)[0] == '|' && (*arg)[1] == '|')
4301     {
4302 	if (evaluate && first)
4303 	{
4304 	    if (get_tv_number_chk(rettv, &error) != 0)
4305 		result = TRUE;
4306 	    clear_tv(rettv);
4307 	    if (error)
4308 		return FAIL;
4309 	    first = FALSE;
4310 	}
4311 
4312 	/*
4313 	 * Get the second variable.
4314 	 */
4315 	*arg = skipwhite(*arg + 2);
4316 	if (eval3(arg, &var2, evaluate && !result) == FAIL)
4317 	    return FAIL;
4318 
4319 	/*
4320 	 * Compute the result.
4321 	 */
4322 	if (evaluate && !result)
4323 	{
4324 	    if (get_tv_number_chk(&var2, &error) != 0)
4325 		result = TRUE;
4326 	    clear_tv(&var2);
4327 	    if (error)
4328 		return FAIL;
4329 	}
4330 	if (evaluate)
4331 	{
4332 	    rettv->v_type = VAR_NUMBER;
4333 	    rettv->vval.v_number = result;
4334 	}
4335     }
4336 
4337     return OK;
4338 }
4339 
4340 /*
4341  * Handle second level expression:
4342  *	expr3 && expr3 && expr3	    logical AND
4343  *
4344  * "arg" must point to the first non-white of the expression.
4345  * "arg" is advanced to the next non-white after the recognized expression.
4346  *
4347  * Return OK or FAIL.
4348  */
4349     static int
4350 eval3(char_u **arg, typval_T *rettv, int evaluate)
4351 {
4352     typval_T	var2;
4353     long	result;
4354     int		first;
4355     int		error = FALSE;
4356 
4357     /*
4358      * Get the first variable.
4359      */
4360     if (eval4(arg, rettv, evaluate) == FAIL)
4361 	return FAIL;
4362 
4363     /*
4364      * Repeat until there is no following "&&".
4365      */
4366     first = TRUE;
4367     result = TRUE;
4368     while ((*arg)[0] == '&' && (*arg)[1] == '&')
4369     {
4370 	if (evaluate && first)
4371 	{
4372 	    if (get_tv_number_chk(rettv, &error) == 0)
4373 		result = FALSE;
4374 	    clear_tv(rettv);
4375 	    if (error)
4376 		return FAIL;
4377 	    first = FALSE;
4378 	}
4379 
4380 	/*
4381 	 * Get the second variable.
4382 	 */
4383 	*arg = skipwhite(*arg + 2);
4384 	if (eval4(arg, &var2, evaluate && result) == FAIL)
4385 	    return FAIL;
4386 
4387 	/*
4388 	 * Compute the result.
4389 	 */
4390 	if (evaluate && result)
4391 	{
4392 	    if (get_tv_number_chk(&var2, &error) == 0)
4393 		result = FALSE;
4394 	    clear_tv(&var2);
4395 	    if (error)
4396 		return FAIL;
4397 	}
4398 	if (evaluate)
4399 	{
4400 	    rettv->v_type = VAR_NUMBER;
4401 	    rettv->vval.v_number = result;
4402 	}
4403     }
4404 
4405     return OK;
4406 }
4407 
4408 /*
4409  * Handle third level expression:
4410  *	var1 == var2
4411  *	var1 =~ var2
4412  *	var1 != var2
4413  *	var1 !~ var2
4414  *	var1 > var2
4415  *	var1 >= var2
4416  *	var1 < var2
4417  *	var1 <= var2
4418  *	var1 is var2
4419  *	var1 isnot var2
4420  *
4421  * "arg" must point to the first non-white of the expression.
4422  * "arg" is advanced to the next non-white after the recognized expression.
4423  *
4424  * Return OK or FAIL.
4425  */
4426     static int
4427 eval4(char_u **arg, typval_T *rettv, int evaluate)
4428 {
4429     typval_T	var2;
4430     char_u	*p;
4431     int		i;
4432     exptype_T	type = TYPE_UNKNOWN;
4433     int		type_is = FALSE;    /* TRUE for "is" and "isnot" */
4434     int		len = 2;
4435     long	n1, n2;
4436     char_u	*s1, *s2;
4437     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
4438     int		ic;
4439 
4440     /*
4441      * Get the first variable.
4442      */
4443     if (eval5(arg, rettv, evaluate) == FAIL)
4444 	return FAIL;
4445 
4446     p = *arg;
4447     switch (p[0])
4448     {
4449 	case '=':   if (p[1] == '=')
4450 			type = TYPE_EQUAL;
4451 		    else if (p[1] == '~')
4452 			type = TYPE_MATCH;
4453 		    break;
4454 	case '!':   if (p[1] == '=')
4455 			type = TYPE_NEQUAL;
4456 		    else if (p[1] == '~')
4457 			type = TYPE_NOMATCH;
4458 		    break;
4459 	case '>':   if (p[1] != '=')
4460 		    {
4461 			type = TYPE_GREATER;
4462 			len = 1;
4463 		    }
4464 		    else
4465 			type = TYPE_GEQUAL;
4466 		    break;
4467 	case '<':   if (p[1] != '=')
4468 		    {
4469 			type = TYPE_SMALLER;
4470 			len = 1;
4471 		    }
4472 		    else
4473 			type = TYPE_SEQUAL;
4474 		    break;
4475 	case 'i':   if (p[1] == 's')
4476 		    {
4477 			if (p[2] == 'n' && p[3] == 'o' && p[4] == 't')
4478 			    len = 5;
4479 			i = p[len];
4480 			if (!isalnum(i) && i != '_')
4481 			{
4482 			    type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL;
4483 			    type_is = TRUE;
4484 			}
4485 		    }
4486 		    break;
4487     }
4488 
4489     /*
4490      * If there is a comparative operator, use it.
4491      */
4492     if (type != TYPE_UNKNOWN)
4493     {
4494 	/* extra question mark appended: ignore case */
4495 	if (p[len] == '?')
4496 	{
4497 	    ic = TRUE;
4498 	    ++len;
4499 	}
4500 	/* extra '#' appended: match case */
4501 	else if (p[len] == '#')
4502 	{
4503 	    ic = FALSE;
4504 	    ++len;
4505 	}
4506 	/* nothing appended: use 'ignorecase' */
4507 	else
4508 	    ic = p_ic;
4509 
4510 	/*
4511 	 * Get the second variable.
4512 	 */
4513 	*arg = skipwhite(p + len);
4514 	if (eval5(arg, &var2, evaluate) == FAIL)
4515 	{
4516 	    clear_tv(rettv);
4517 	    return FAIL;
4518 	}
4519 
4520 	if (evaluate)
4521 	{
4522 	    if (type_is && rettv->v_type != var2.v_type)
4523 	    {
4524 		/* For "is" a different type always means FALSE, for "notis"
4525 		 * it means TRUE. */
4526 		n1 = (type == TYPE_NEQUAL);
4527 	    }
4528 	    else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST)
4529 	    {
4530 		if (type_is)
4531 		{
4532 		    n1 = (rettv->v_type == var2.v_type
4533 				   && rettv->vval.v_list == var2.vval.v_list);
4534 		    if (type == TYPE_NEQUAL)
4535 			n1 = !n1;
4536 		}
4537 		else if (rettv->v_type != var2.v_type
4538 			|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
4539 		{
4540 		    if (rettv->v_type != var2.v_type)
4541 			EMSG(_("E691: Can only compare List with List"));
4542 		    else
4543 			EMSG(_("E692: Invalid operation for List"));
4544 		    clear_tv(rettv);
4545 		    clear_tv(&var2);
4546 		    return FAIL;
4547 		}
4548 		else
4549 		{
4550 		    /* Compare two Lists for being equal or unequal. */
4551 		    n1 = list_equal(rettv->vval.v_list, var2.vval.v_list,
4552 								   ic, FALSE);
4553 		    if (type == TYPE_NEQUAL)
4554 			n1 = !n1;
4555 		}
4556 	    }
4557 
4558 	    else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT)
4559 	    {
4560 		if (type_is)
4561 		{
4562 		    n1 = (rettv->v_type == var2.v_type
4563 				   && rettv->vval.v_dict == var2.vval.v_dict);
4564 		    if (type == TYPE_NEQUAL)
4565 			n1 = !n1;
4566 		}
4567 		else if (rettv->v_type != var2.v_type
4568 			|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
4569 		{
4570 		    if (rettv->v_type != var2.v_type)
4571 			EMSG(_("E735: Can only compare Dictionary with Dictionary"));
4572 		    else
4573 			EMSG(_("E736: Invalid operation for Dictionary"));
4574 		    clear_tv(rettv);
4575 		    clear_tv(&var2);
4576 		    return FAIL;
4577 		}
4578 		else
4579 		{
4580 		    /* Compare two Dictionaries for being equal or unequal. */
4581 		    n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict,
4582 								   ic, FALSE);
4583 		    if (type == TYPE_NEQUAL)
4584 			n1 = !n1;
4585 		}
4586 	    }
4587 
4588 	    else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC
4589 		|| rettv->v_type == VAR_PARTIAL || var2.v_type == VAR_PARTIAL)
4590 	    {
4591 		if (type != TYPE_EQUAL && type != TYPE_NEQUAL)
4592 		{
4593 		    EMSG(_("E694: Invalid operation for Funcrefs"));
4594 		    clear_tv(rettv);
4595 		    clear_tv(&var2);
4596 		    return FAIL;
4597 		}
4598 		n1 = tv_equal(rettv, &var2, FALSE, FALSE);
4599 		if (type == TYPE_NEQUAL)
4600 		    n1 = !n1;
4601 	    }
4602 
4603 #ifdef FEAT_FLOAT
4604 	    /*
4605 	     * If one of the two variables is a float, compare as a float.
4606 	     * When using "=~" or "!~", always compare as string.
4607 	     */
4608 	    else if ((rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
4609 		    && type != TYPE_MATCH && type != TYPE_NOMATCH)
4610 	    {
4611 		float_T f1, f2;
4612 
4613 		if (rettv->v_type == VAR_FLOAT)
4614 		    f1 = rettv->vval.v_float;
4615 		else
4616 		    f1 = get_tv_number(rettv);
4617 		if (var2.v_type == VAR_FLOAT)
4618 		    f2 = var2.vval.v_float;
4619 		else
4620 		    f2 = get_tv_number(&var2);
4621 		n1 = FALSE;
4622 		switch (type)
4623 		{
4624 		    case TYPE_EQUAL:    n1 = (f1 == f2); break;
4625 		    case TYPE_NEQUAL:   n1 = (f1 != f2); break;
4626 		    case TYPE_GREATER:  n1 = (f1 > f2); break;
4627 		    case TYPE_GEQUAL:   n1 = (f1 >= f2); break;
4628 		    case TYPE_SMALLER:  n1 = (f1 < f2); break;
4629 		    case TYPE_SEQUAL:   n1 = (f1 <= f2); break;
4630 		    case TYPE_UNKNOWN:
4631 		    case TYPE_MATCH:
4632 		    case TYPE_NOMATCH:  break;  /* avoid gcc warning */
4633 		}
4634 	    }
4635 #endif
4636 
4637 	    /*
4638 	     * If one of the two variables is a number, compare as a number.
4639 	     * When using "=~" or "!~", always compare as string.
4640 	     */
4641 	    else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER)
4642 		    && type != TYPE_MATCH && type != TYPE_NOMATCH)
4643 	    {
4644 		n1 = get_tv_number(rettv);
4645 		n2 = get_tv_number(&var2);
4646 		switch (type)
4647 		{
4648 		    case TYPE_EQUAL:    n1 = (n1 == n2); break;
4649 		    case TYPE_NEQUAL:   n1 = (n1 != n2); break;
4650 		    case TYPE_GREATER:  n1 = (n1 > n2); break;
4651 		    case TYPE_GEQUAL:   n1 = (n1 >= n2); break;
4652 		    case TYPE_SMALLER:  n1 = (n1 < n2); break;
4653 		    case TYPE_SEQUAL:   n1 = (n1 <= n2); break;
4654 		    case TYPE_UNKNOWN:
4655 		    case TYPE_MATCH:
4656 		    case TYPE_NOMATCH:  break;  /* avoid gcc warning */
4657 		}
4658 	    }
4659 	    else
4660 	    {
4661 		s1 = get_tv_string_buf(rettv, buf1);
4662 		s2 = get_tv_string_buf(&var2, buf2);
4663 		if (type != TYPE_MATCH && type != TYPE_NOMATCH)
4664 		    i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
4665 		else
4666 		    i = 0;
4667 		n1 = FALSE;
4668 		switch (type)
4669 		{
4670 		    case TYPE_EQUAL:    n1 = (i == 0); break;
4671 		    case TYPE_NEQUAL:   n1 = (i != 0); break;
4672 		    case TYPE_GREATER:  n1 = (i > 0); break;
4673 		    case TYPE_GEQUAL:   n1 = (i >= 0); break;
4674 		    case TYPE_SMALLER:  n1 = (i < 0); break;
4675 		    case TYPE_SEQUAL:   n1 = (i <= 0); break;
4676 
4677 		    case TYPE_MATCH:
4678 		    case TYPE_NOMATCH:
4679 			    n1 = pattern_match(s2, s1, ic);
4680 			    if (type == TYPE_NOMATCH)
4681 				n1 = !n1;
4682 			    break;
4683 
4684 		    case TYPE_UNKNOWN:  break;  /* avoid gcc warning */
4685 		}
4686 	    }
4687 	    clear_tv(rettv);
4688 	    clear_tv(&var2);
4689 	    rettv->v_type = VAR_NUMBER;
4690 	    rettv->vval.v_number = n1;
4691 	}
4692     }
4693 
4694     return OK;
4695 }
4696 
4697 /*
4698  * Handle fourth level expression:
4699  *	+	number addition
4700  *	-	number subtraction
4701  *	.	string concatenation
4702  *
4703  * "arg" must point to the first non-white of the expression.
4704  * "arg" is advanced to the next non-white after the recognized expression.
4705  *
4706  * Return OK or FAIL.
4707  */
4708     static int
4709 eval5(char_u **arg, typval_T *rettv, int evaluate)
4710 {
4711     typval_T	var2;
4712     typval_T	var3;
4713     int		op;
4714     long	n1, n2;
4715 #ifdef FEAT_FLOAT
4716     float_T	f1 = 0, f2 = 0;
4717 #endif
4718     char_u	*s1, *s2;
4719     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
4720     char_u	*p;
4721 
4722     /*
4723      * Get the first variable.
4724      */
4725     if (eval6(arg, rettv, evaluate, FALSE) == FAIL)
4726 	return FAIL;
4727 
4728     /*
4729      * Repeat computing, until no '+', '-' or '.' is following.
4730      */
4731     for (;;)
4732     {
4733 	op = **arg;
4734 	if (op != '+' && op != '-' && op != '.')
4735 	    break;
4736 
4737 	if ((op != '+' || rettv->v_type != VAR_LIST)
4738 #ifdef FEAT_FLOAT
4739 		&& (op == '.' || rettv->v_type != VAR_FLOAT)
4740 #endif
4741 		)
4742 	{
4743 	    /* For "list + ...", an illegal use of the first operand as
4744 	     * a number cannot be determined before evaluating the 2nd
4745 	     * operand: if this is also a list, all is ok.
4746 	     * For "something . ...", "something - ..." or "non-list + ...",
4747 	     * we know that the first operand needs to be a string or number
4748 	     * without evaluating the 2nd operand.  So check before to avoid
4749 	     * side effects after an error. */
4750 	    if (evaluate && get_tv_string_chk(rettv) == NULL)
4751 	    {
4752 		clear_tv(rettv);
4753 		return FAIL;
4754 	    }
4755 	}
4756 
4757 	/*
4758 	 * Get the second variable.
4759 	 */
4760 	*arg = skipwhite(*arg + 1);
4761 	if (eval6(arg, &var2, evaluate, op == '.') == FAIL)
4762 	{
4763 	    clear_tv(rettv);
4764 	    return FAIL;
4765 	}
4766 
4767 	if (evaluate)
4768 	{
4769 	    /*
4770 	     * Compute the result.
4771 	     */
4772 	    if (op == '.')
4773 	    {
4774 		s1 = get_tv_string_buf(rettv, buf1);	/* already checked */
4775 		s2 = get_tv_string_buf_chk(&var2, buf2);
4776 		if (s2 == NULL)		/* type error ? */
4777 		{
4778 		    clear_tv(rettv);
4779 		    clear_tv(&var2);
4780 		    return FAIL;
4781 		}
4782 		p = concat_str(s1, s2);
4783 		clear_tv(rettv);
4784 		rettv->v_type = VAR_STRING;
4785 		rettv->vval.v_string = p;
4786 	    }
4787 	    else if (op == '+' && rettv->v_type == VAR_LIST
4788 						   && var2.v_type == VAR_LIST)
4789 	    {
4790 		/* concatenate Lists */
4791 		if (list_concat(rettv->vval.v_list, var2.vval.v_list,
4792 							       &var3) == FAIL)
4793 		{
4794 		    clear_tv(rettv);
4795 		    clear_tv(&var2);
4796 		    return FAIL;
4797 		}
4798 		clear_tv(rettv);
4799 		*rettv = var3;
4800 	    }
4801 	    else
4802 	    {
4803 		int	    error = FALSE;
4804 
4805 #ifdef FEAT_FLOAT
4806 		if (rettv->v_type == VAR_FLOAT)
4807 		{
4808 		    f1 = rettv->vval.v_float;
4809 		    n1 = 0;
4810 		}
4811 		else
4812 #endif
4813 		{
4814 		    n1 = get_tv_number_chk(rettv, &error);
4815 		    if (error)
4816 		    {
4817 			/* This can only happen for "list + non-list".  For
4818 			 * "non-list + ..." or "something - ...", we returned
4819 			 * before evaluating the 2nd operand. */
4820 			clear_tv(rettv);
4821 			return FAIL;
4822 		    }
4823 #ifdef FEAT_FLOAT
4824 		    if (var2.v_type == VAR_FLOAT)
4825 			f1 = n1;
4826 #endif
4827 		}
4828 #ifdef FEAT_FLOAT
4829 		if (var2.v_type == VAR_FLOAT)
4830 		{
4831 		    f2 = var2.vval.v_float;
4832 		    n2 = 0;
4833 		}
4834 		else
4835 #endif
4836 		{
4837 		    n2 = get_tv_number_chk(&var2, &error);
4838 		    if (error)
4839 		    {
4840 			clear_tv(rettv);
4841 			clear_tv(&var2);
4842 			return FAIL;
4843 		    }
4844 #ifdef FEAT_FLOAT
4845 		    if (rettv->v_type == VAR_FLOAT)
4846 			f2 = n2;
4847 #endif
4848 		}
4849 		clear_tv(rettv);
4850 
4851 #ifdef FEAT_FLOAT
4852 		/* If there is a float on either side the result is a float. */
4853 		if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT)
4854 		{
4855 		    if (op == '+')
4856 			f1 = f1 + f2;
4857 		    else
4858 			f1 = f1 - f2;
4859 		    rettv->v_type = VAR_FLOAT;
4860 		    rettv->vval.v_float = f1;
4861 		}
4862 		else
4863 #endif
4864 		{
4865 		    if (op == '+')
4866 			n1 = n1 + n2;
4867 		    else
4868 			n1 = n1 - n2;
4869 		    rettv->v_type = VAR_NUMBER;
4870 		    rettv->vval.v_number = n1;
4871 		}
4872 	    }
4873 	    clear_tv(&var2);
4874 	}
4875     }
4876     return OK;
4877 }
4878 
4879 /*
4880  * Handle fifth level expression:
4881  *	*	number multiplication
4882  *	/	number division
4883  *	%	number modulo
4884  *
4885  * "arg" must point to the first non-white of the expression.
4886  * "arg" is advanced to the next non-white after the recognized expression.
4887  *
4888  * Return OK or FAIL.
4889  */
4890     static int
4891 eval6(
4892     char_u	**arg,
4893     typval_T	*rettv,
4894     int		evaluate,
4895     int		want_string)  /* after "." operator */
4896 {
4897     typval_T	var2;
4898     int		op;
4899     long	n1, n2;
4900 #ifdef FEAT_FLOAT
4901     int		use_float = FALSE;
4902     float_T	f1 = 0, f2;
4903 #endif
4904     int		error = FALSE;
4905 
4906     /*
4907      * Get the first variable.
4908      */
4909     if (eval7(arg, rettv, evaluate, want_string) == FAIL)
4910 	return FAIL;
4911 
4912     /*
4913      * Repeat computing, until no '*', '/' or '%' is following.
4914      */
4915     for (;;)
4916     {
4917 	op = **arg;
4918 	if (op != '*' && op != '/' && op != '%')
4919 	    break;
4920 
4921 	if (evaluate)
4922 	{
4923 #ifdef FEAT_FLOAT
4924 	    if (rettv->v_type == VAR_FLOAT)
4925 	    {
4926 		f1 = rettv->vval.v_float;
4927 		use_float = TRUE;
4928 		n1 = 0;
4929 	    }
4930 	    else
4931 #endif
4932 		n1 = get_tv_number_chk(rettv, &error);
4933 	    clear_tv(rettv);
4934 	    if (error)
4935 		return FAIL;
4936 	}
4937 	else
4938 	    n1 = 0;
4939 
4940 	/*
4941 	 * Get the second variable.
4942 	 */
4943 	*arg = skipwhite(*arg + 1);
4944 	if (eval7(arg, &var2, evaluate, FALSE) == FAIL)
4945 	    return FAIL;
4946 
4947 	if (evaluate)
4948 	{
4949 #ifdef FEAT_FLOAT
4950 	    if (var2.v_type == VAR_FLOAT)
4951 	    {
4952 		if (!use_float)
4953 		{
4954 		    f1 = n1;
4955 		    use_float = TRUE;
4956 		}
4957 		f2 = var2.vval.v_float;
4958 		n2 = 0;
4959 	    }
4960 	    else
4961 #endif
4962 	    {
4963 		n2 = get_tv_number_chk(&var2, &error);
4964 		clear_tv(&var2);
4965 		if (error)
4966 		    return FAIL;
4967 #ifdef FEAT_FLOAT
4968 		if (use_float)
4969 		    f2 = n2;
4970 #endif
4971 	    }
4972 
4973 	    /*
4974 	     * Compute the result.
4975 	     * When either side is a float the result is a float.
4976 	     */
4977 #ifdef FEAT_FLOAT
4978 	    if (use_float)
4979 	    {
4980 		if (op == '*')
4981 		    f1 = f1 * f2;
4982 		else if (op == '/')
4983 		{
4984 # ifdef VMS
4985 		    /* VMS crashes on divide by zero, work around it */
4986 		    if (f2 == 0.0)
4987 		    {
4988 			if (f1 == 0)
4989 			    f1 = -1 * __F_FLT_MAX - 1L;   /* similar to NaN */
4990 			else if (f1 < 0)
4991 			    f1 = -1 * __F_FLT_MAX;
4992 			else
4993 			    f1 = __F_FLT_MAX;
4994 		    }
4995 		    else
4996 			f1 = f1 / f2;
4997 # else
4998 		    /* We rely on the floating point library to handle divide
4999 		     * by zero to result in "inf" and not a crash. */
5000 		    f1 = f1 / f2;
5001 # endif
5002 		}
5003 		else
5004 		{
5005 		    EMSG(_("E804: Cannot use '%' with Float"));
5006 		    return FAIL;
5007 		}
5008 		rettv->v_type = VAR_FLOAT;
5009 		rettv->vval.v_float = f1;
5010 	    }
5011 	    else
5012 #endif
5013 	    {
5014 		if (op == '*')
5015 		    n1 = n1 * n2;
5016 		else if (op == '/')
5017 		{
5018 		    if (n2 == 0)	/* give an error message? */
5019 		    {
5020 			if (n1 == 0)
5021 			    n1 = -0x7fffffffL - 1L;	/* similar to NaN */
5022 			else if (n1 < 0)
5023 			    n1 = -0x7fffffffL;
5024 			else
5025 			    n1 = 0x7fffffffL;
5026 		    }
5027 		    else
5028 			n1 = n1 / n2;
5029 		}
5030 		else
5031 		{
5032 		    if (n2 == 0)	/* give an error message? */
5033 			n1 = 0;
5034 		    else
5035 			n1 = n1 % n2;
5036 		}
5037 		rettv->v_type = VAR_NUMBER;
5038 		rettv->vval.v_number = n1;
5039 	    }
5040 	}
5041     }
5042 
5043     return OK;
5044 }
5045 
5046 /*
5047  * Handle sixth level expression:
5048  *  number		number constant
5049  *  "string"		string constant
5050  *  'string'		literal string constant
5051  *  &option-name	option value
5052  *  @r			register contents
5053  *  identifier		variable value
5054  *  function()		function call
5055  *  $VAR		environment variable
5056  *  (expression)	nested expression
5057  *  [expr, expr]	List
5058  *  {key: val, key: val}  Dictionary
5059  *
5060  *  Also handle:
5061  *  ! in front		logical NOT
5062  *  - in front		unary minus
5063  *  + in front		unary plus (ignored)
5064  *  trailing []		subscript in String or List
5065  *  trailing .name	entry in Dictionary
5066  *
5067  * "arg" must point to the first non-white of the expression.
5068  * "arg" is advanced to the next non-white after the recognized expression.
5069  *
5070  * Return OK or FAIL.
5071  */
5072     static int
5073 eval7(
5074     char_u	**arg,
5075     typval_T	*rettv,
5076     int		evaluate,
5077     int		want_string UNUSED)	/* after "." operator */
5078 {
5079     long	n;
5080     int		len;
5081     char_u	*s;
5082     char_u	*start_leader, *end_leader;
5083     int		ret = OK;
5084     char_u	*alias;
5085 
5086     /*
5087      * Initialise variable so that clear_tv() can't mistake this for a
5088      * string and free a string that isn't there.
5089      */
5090     rettv->v_type = VAR_UNKNOWN;
5091 
5092     /*
5093      * Skip '!' and '-' characters.  They are handled later.
5094      */
5095     start_leader = *arg;
5096     while (**arg == '!' || **arg == '-' || **arg == '+')
5097 	*arg = skipwhite(*arg + 1);
5098     end_leader = *arg;
5099 
5100     switch (**arg)
5101     {
5102     /*
5103      * Number constant.
5104      */
5105     case '0':
5106     case '1':
5107     case '2':
5108     case '3':
5109     case '4':
5110     case '5':
5111     case '6':
5112     case '7':
5113     case '8':
5114     case '9':
5115 	{
5116 #ifdef FEAT_FLOAT
5117 		char_u *p = skipdigits(*arg + 1);
5118 		int    get_float = FALSE;
5119 
5120 		/* We accept a float when the format matches
5121 		 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?".  This is very
5122 		 * strict to avoid backwards compatibility problems.
5123 		 * Don't look for a float after the "." operator, so that
5124 		 * ":let vers = 1.2.3" doesn't fail. */
5125 		if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
5126 		{
5127 		    get_float = TRUE;
5128 		    p = skipdigits(p + 2);
5129 		    if (*p == 'e' || *p == 'E')
5130 		    {
5131 			++p;
5132 			if (*p == '-' || *p == '+')
5133 			    ++p;
5134 			if (!vim_isdigit(*p))
5135 			    get_float = FALSE;
5136 			else
5137 			    p = skipdigits(p + 1);
5138 		    }
5139 		    if (ASCII_ISALPHA(*p) || *p == '.')
5140 			get_float = FALSE;
5141 		}
5142 		if (get_float)
5143 		{
5144 		    float_T	f;
5145 
5146 		    *arg += string2float(*arg, &f);
5147 		    if (evaluate)
5148 		    {
5149 			rettv->v_type = VAR_FLOAT;
5150 			rettv->vval.v_float = f;
5151 		    }
5152 		}
5153 		else
5154 #endif
5155 		{
5156 		    vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0);
5157 		    *arg += len;
5158 		    if (evaluate)
5159 		    {
5160 			rettv->v_type = VAR_NUMBER;
5161 			rettv->vval.v_number = n;
5162 		    }
5163 		}
5164 		break;
5165 	}
5166 
5167     /*
5168      * String constant: "string".
5169      */
5170     case '"':	ret = get_string_tv(arg, rettv, evaluate);
5171 		break;
5172 
5173     /*
5174      * Literal string constant: 'str''ing'.
5175      */
5176     case '\'':	ret = get_lit_string_tv(arg, rettv, evaluate);
5177 		break;
5178 
5179     /*
5180      * List: [expr, expr]
5181      */
5182     case '[':	ret = get_list_tv(arg, rettv, evaluate);
5183 		break;
5184 
5185     /*
5186      * Dictionary: {key: val, key: val}
5187      */
5188     case '{':	ret = get_dict_tv(arg, rettv, evaluate);
5189 		break;
5190 
5191     /*
5192      * Option value: &name
5193      */
5194     case '&':	ret = get_option_tv(arg, rettv, evaluate);
5195 		break;
5196 
5197     /*
5198      * Environment variable: $VAR.
5199      */
5200     case '$':	ret = get_env_tv(arg, rettv, evaluate);
5201 		break;
5202 
5203     /*
5204      * Register contents: @r.
5205      */
5206     case '@':	++*arg;
5207 		if (evaluate)
5208 		{
5209 		    rettv->v_type = VAR_STRING;
5210 		    rettv->vval.v_string = get_reg_contents(**arg,
5211 							    GREG_EXPR_SRC);
5212 		}
5213 		if (**arg != NUL)
5214 		    ++*arg;
5215 		break;
5216 
5217     /*
5218      * nested expression: (expression).
5219      */
5220     case '(':	*arg = skipwhite(*arg + 1);
5221 		ret = eval1(arg, rettv, evaluate);	/* recursive! */
5222 		if (**arg == ')')
5223 		    ++*arg;
5224 		else if (ret == OK)
5225 		{
5226 		    EMSG(_("E110: Missing ')'"));
5227 		    clear_tv(rettv);
5228 		    ret = FAIL;
5229 		}
5230 		break;
5231 
5232     default:	ret = NOTDONE;
5233 		break;
5234     }
5235 
5236     if (ret == NOTDONE)
5237     {
5238 	/*
5239 	 * Must be a variable or function name.
5240 	 * Can also be a curly-braces kind of name: {expr}.
5241 	 */
5242 	s = *arg;
5243 	len = get_name_len(arg, &alias, evaluate, TRUE);
5244 	if (alias != NULL)
5245 	    s = alias;
5246 
5247 	if (len <= 0)
5248 	    ret = FAIL;
5249 	else
5250 	{
5251 	    if (**arg == '(')		/* recursive! */
5252 	    {
5253 		partial_T *partial;
5254 
5255 		/* If "s" is the name of a variable of type VAR_FUNC
5256 		 * use its contents. */
5257 		s = deref_func_name(s, &len, &partial, !evaluate);
5258 
5259 		/* Invoke the function. */
5260 		ret = get_func_tv(s, len, rettv, arg,
5261 			  curwin->w_cursor.lnum, curwin->w_cursor.lnum,
5262 			  &len, evaluate, partial, NULL);
5263 
5264 		/* If evaluate is FALSE rettv->v_type was not set in
5265 		 * get_func_tv, but it's needed in handle_subscript() to parse
5266 		 * what follows. So set it here. */
5267 		if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(')
5268 		{
5269 		    rettv->vval.v_string = vim_strsave((char_u *)"");
5270 		    rettv->v_type = VAR_FUNC;
5271 		}
5272 
5273 		/* Stop the expression evaluation when immediately
5274 		 * aborting on error, or when an interrupt occurred or
5275 		 * an exception was thrown but not caught. */
5276 		if (aborting())
5277 		{
5278 		    if (ret == OK)
5279 			clear_tv(rettv);
5280 		    ret = FAIL;
5281 		}
5282 	    }
5283 	    else if (evaluate)
5284 		ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE);
5285 	    else
5286 		ret = OK;
5287 	}
5288 	vim_free(alias);
5289     }
5290 
5291     *arg = skipwhite(*arg);
5292 
5293     /* Handle following '[', '(' and '.' for expr[expr], expr.name,
5294      * expr(expr). */
5295     if (ret == OK)
5296 	ret = handle_subscript(arg, rettv, evaluate, TRUE);
5297 
5298     /*
5299      * Apply logical NOT and unary '-', from right to left, ignore '+'.
5300      */
5301     if (ret == OK && evaluate && end_leader > start_leader)
5302     {
5303 	int	    error = FALSE;
5304 	int	    val = 0;
5305 #ifdef FEAT_FLOAT
5306 	float_T	    f = 0.0;
5307 
5308 	if (rettv->v_type == VAR_FLOAT)
5309 	    f = rettv->vval.v_float;
5310 	else
5311 #endif
5312 	    val = get_tv_number_chk(rettv, &error);
5313 	if (error)
5314 	{
5315 	    clear_tv(rettv);
5316 	    ret = FAIL;
5317 	}
5318 	else
5319 	{
5320 	    while (end_leader > start_leader)
5321 	    {
5322 		--end_leader;
5323 		if (*end_leader == '!')
5324 		{
5325 #ifdef FEAT_FLOAT
5326 		    if (rettv->v_type == VAR_FLOAT)
5327 			f = !f;
5328 		    else
5329 #endif
5330 			val = !val;
5331 		}
5332 		else if (*end_leader == '-')
5333 		{
5334 #ifdef FEAT_FLOAT
5335 		    if (rettv->v_type == VAR_FLOAT)
5336 			f = -f;
5337 		    else
5338 #endif
5339 			val = -val;
5340 		}
5341 	    }
5342 #ifdef FEAT_FLOAT
5343 	    if (rettv->v_type == VAR_FLOAT)
5344 	    {
5345 		clear_tv(rettv);
5346 		rettv->vval.v_float = f;
5347 	    }
5348 	    else
5349 #endif
5350 	    {
5351 		clear_tv(rettv);
5352 		rettv->v_type = VAR_NUMBER;
5353 		rettv->vval.v_number = val;
5354 	    }
5355 	}
5356     }
5357 
5358     return ret;
5359 }
5360 
5361 /*
5362  * Evaluate an "[expr]" or "[expr:expr]" index.  Also "dict.key".
5363  * "*arg" points to the '[' or '.'.
5364  * Returns FAIL or OK. "*arg" is advanced to after the ']'.
5365  */
5366     static int
5367 eval_index(
5368     char_u	**arg,
5369     typval_T	*rettv,
5370     int		evaluate,
5371     int		verbose)	/* give error messages */
5372 {
5373     int		empty1 = FALSE, empty2 = FALSE;
5374     typval_T	var1, var2;
5375     long	n1, n2 = 0;
5376     long	len = -1;
5377     int		range = FALSE;
5378     char_u	*s;
5379     char_u	*key = NULL;
5380 
5381     switch (rettv->v_type)
5382     {
5383 	case VAR_FUNC:
5384 	case VAR_PARTIAL:
5385 	    if (verbose)
5386 		EMSG(_("E695: Cannot index a Funcref"));
5387 	    return FAIL;
5388 	case VAR_FLOAT:
5389 #ifdef FEAT_FLOAT
5390 	    if (verbose)
5391 		EMSG(_(e_float_as_string));
5392 	    return FAIL;
5393 #endif
5394 	case VAR_SPECIAL:
5395 	case VAR_JOB:
5396 	case VAR_CHANNEL:
5397 	    if (verbose)
5398 		EMSG(_("E909: Cannot index a special variable"));
5399 	    return FAIL;
5400 	case VAR_UNKNOWN:
5401 	    if (evaluate)
5402 		return FAIL;
5403 	    /* FALLTHROUGH */
5404 
5405 	case VAR_STRING:
5406 	case VAR_NUMBER:
5407 	case VAR_LIST:
5408 	case VAR_DICT:
5409 	    break;
5410     }
5411 
5412     init_tv(&var1);
5413     init_tv(&var2);
5414     if (**arg == '.')
5415     {
5416 	/*
5417 	 * dict.name
5418 	 */
5419 	key = *arg + 1;
5420 	for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
5421 	    ;
5422 	if (len == 0)
5423 	    return FAIL;
5424 	*arg = skipwhite(key + len);
5425     }
5426     else
5427     {
5428 	/*
5429 	 * something[idx]
5430 	 *
5431 	 * Get the (first) variable from inside the [].
5432 	 */
5433 	*arg = skipwhite(*arg + 1);
5434 	if (**arg == ':')
5435 	    empty1 = TRUE;
5436 	else if (eval1(arg, &var1, evaluate) == FAIL)	/* recursive! */
5437 	    return FAIL;
5438 	else if (evaluate && get_tv_string_chk(&var1) == NULL)
5439 	{
5440 	    /* not a number or string */
5441 	    clear_tv(&var1);
5442 	    return FAIL;
5443 	}
5444 
5445 	/*
5446 	 * Get the second variable from inside the [:].
5447 	 */
5448 	if (**arg == ':')
5449 	{
5450 	    range = TRUE;
5451 	    *arg = skipwhite(*arg + 1);
5452 	    if (**arg == ']')
5453 		empty2 = TRUE;
5454 	    else if (eval1(arg, &var2, evaluate) == FAIL)	/* recursive! */
5455 	    {
5456 		if (!empty1)
5457 		    clear_tv(&var1);
5458 		return FAIL;
5459 	    }
5460 	    else if (evaluate && get_tv_string_chk(&var2) == NULL)
5461 	    {
5462 		/* not a number or string */
5463 		if (!empty1)
5464 		    clear_tv(&var1);
5465 		clear_tv(&var2);
5466 		return FAIL;
5467 	    }
5468 	}
5469 
5470 	/* Check for the ']'. */
5471 	if (**arg != ']')
5472 	{
5473 	    if (verbose)
5474 		EMSG(_(e_missbrac));
5475 	    clear_tv(&var1);
5476 	    if (range)
5477 		clear_tv(&var2);
5478 	    return FAIL;
5479 	}
5480 	*arg = skipwhite(*arg + 1);	/* skip the ']' */
5481     }
5482 
5483     if (evaluate)
5484     {
5485 	n1 = 0;
5486 	if (!empty1 && rettv->v_type != VAR_DICT)
5487 	{
5488 	    n1 = get_tv_number(&var1);
5489 	    clear_tv(&var1);
5490 	}
5491 	if (range)
5492 	{
5493 	    if (empty2)
5494 		n2 = -1;
5495 	    else
5496 	    {
5497 		n2 = get_tv_number(&var2);
5498 		clear_tv(&var2);
5499 	    }
5500 	}
5501 
5502 	switch (rettv->v_type)
5503 	{
5504 	    case VAR_UNKNOWN:
5505 	    case VAR_FUNC:
5506 	    case VAR_PARTIAL:
5507 	    case VAR_FLOAT:
5508 	    case VAR_SPECIAL:
5509 	    case VAR_JOB:
5510 	    case VAR_CHANNEL:
5511 		break; /* not evaluating, skipping over subscript */
5512 
5513 	    case VAR_NUMBER:
5514 	    case VAR_STRING:
5515 		s = get_tv_string(rettv);
5516 		len = (long)STRLEN(s);
5517 		if (range)
5518 		{
5519 		    /* The resulting variable is a substring.  If the indexes
5520 		     * are out of range the result is empty. */
5521 		    if (n1 < 0)
5522 		    {
5523 			n1 = len + n1;
5524 			if (n1 < 0)
5525 			    n1 = 0;
5526 		    }
5527 		    if (n2 < 0)
5528 			n2 = len + n2;
5529 		    else if (n2 >= len)
5530 			n2 = len;
5531 		    if (n1 >= len || n2 < 0 || n1 > n2)
5532 			s = NULL;
5533 		    else
5534 			s = vim_strnsave(s + n1, (int)(n2 - n1 + 1));
5535 		}
5536 		else
5537 		{
5538 		    /* The resulting variable is a string of a single
5539 		     * character.  If the index is too big or negative the
5540 		     * result is empty. */
5541 		    if (n1 >= len || n1 < 0)
5542 			s = NULL;
5543 		    else
5544 			s = vim_strnsave(s + n1, 1);
5545 		}
5546 		clear_tv(rettv);
5547 		rettv->v_type = VAR_STRING;
5548 		rettv->vval.v_string = s;
5549 		break;
5550 
5551 	    case VAR_LIST:
5552 		len = list_len(rettv->vval.v_list);
5553 		if (n1 < 0)
5554 		    n1 = len + n1;
5555 		if (!empty1 && (n1 < 0 || n1 >= len))
5556 		{
5557 		    /* For a range we allow invalid values and return an empty
5558 		     * list.  A list index out of range is an error. */
5559 		    if (!range)
5560 		    {
5561 			if (verbose)
5562 			    EMSGN(_(e_listidx), n1);
5563 			return FAIL;
5564 		    }
5565 		    n1 = len;
5566 		}
5567 		if (range)
5568 		{
5569 		    list_T	*l;
5570 		    listitem_T	*item;
5571 
5572 		    if (n2 < 0)
5573 			n2 = len + n2;
5574 		    else if (n2 >= len)
5575 			n2 = len - 1;
5576 		    if (!empty2 && (n2 < 0 || n2 + 1 < n1))
5577 			n2 = -1;
5578 		    l = list_alloc();
5579 		    if (l == NULL)
5580 			return FAIL;
5581 		    for (item = list_find(rettv->vval.v_list, n1);
5582 							       n1 <= n2; ++n1)
5583 		    {
5584 			if (list_append_tv(l, &item->li_tv) == FAIL)
5585 			{
5586 			    list_free(l, TRUE);
5587 			    return FAIL;
5588 			}
5589 			item = item->li_next;
5590 		    }
5591 		    clear_tv(rettv);
5592 		    rettv->v_type = VAR_LIST;
5593 		    rettv->vval.v_list = l;
5594 		    ++l->lv_refcount;
5595 		}
5596 		else
5597 		{
5598 		    copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1);
5599 		    clear_tv(rettv);
5600 		    *rettv = var1;
5601 		}
5602 		break;
5603 
5604 	    case VAR_DICT:
5605 		if (range)
5606 		{
5607 		    if (verbose)
5608 			EMSG(_(e_dictrange));
5609 		    if (len == -1)
5610 			clear_tv(&var1);
5611 		    return FAIL;
5612 		}
5613 		{
5614 		    dictitem_T	*item;
5615 
5616 		    if (len == -1)
5617 		    {
5618 			key = get_tv_string(&var1);
5619 			if (*key == NUL)
5620 			{
5621 			    if (verbose)
5622 				EMSG(_(e_emptykey));
5623 			    clear_tv(&var1);
5624 			    return FAIL;
5625 			}
5626 		    }
5627 
5628 		    item = dict_find(rettv->vval.v_dict, key, (int)len);
5629 
5630 		    if (item == NULL && verbose)
5631 			EMSG2(_(e_dictkey), key);
5632 		    if (len == -1)
5633 			clear_tv(&var1);
5634 		    if (item == NULL)
5635 			return FAIL;
5636 
5637 		    copy_tv(&item->di_tv, &var1);
5638 		    clear_tv(rettv);
5639 		    *rettv = var1;
5640 		}
5641 		break;
5642 	}
5643     }
5644 
5645     return OK;
5646 }
5647 
5648 /*
5649  * Get an option value.
5650  * "arg" points to the '&' or '+' before the option name.
5651  * "arg" is advanced to character after the option name.
5652  * Return OK or FAIL.
5653  */
5654     static int
5655 get_option_tv(
5656     char_u	**arg,
5657     typval_T	*rettv,	/* when NULL, only check if option exists */
5658     int		evaluate)
5659 {
5660     char_u	*option_end;
5661     long	numval;
5662     char_u	*stringval;
5663     int		opt_type;
5664     int		c;
5665     int		working = (**arg == '+');    /* has("+option") */
5666     int		ret = OK;
5667     int		opt_flags;
5668 
5669     /*
5670      * Isolate the option name and find its value.
5671      */
5672     option_end = find_option_end(arg, &opt_flags);
5673     if (option_end == NULL)
5674     {
5675 	if (rettv != NULL)
5676 	    EMSG2(_("E112: Option name missing: %s"), *arg);
5677 	return FAIL;
5678     }
5679 
5680     if (!evaluate)
5681     {
5682 	*arg = option_end;
5683 	return OK;
5684     }
5685 
5686     c = *option_end;
5687     *option_end = NUL;
5688     opt_type = get_option_value(*arg, &numval,
5689 			       rettv == NULL ? NULL : &stringval, opt_flags);
5690 
5691     if (opt_type == -3)			/* invalid name */
5692     {
5693 	if (rettv != NULL)
5694 	    EMSG2(_("E113: Unknown option: %s"), *arg);
5695 	ret = FAIL;
5696     }
5697     else if (rettv != NULL)
5698     {
5699 	if (opt_type == -2)		/* hidden string option */
5700 	{
5701 	    rettv->v_type = VAR_STRING;
5702 	    rettv->vval.v_string = NULL;
5703 	}
5704 	else if (opt_type == -1)	/* hidden number option */
5705 	{
5706 	    rettv->v_type = VAR_NUMBER;
5707 	    rettv->vval.v_number = 0;
5708 	}
5709 	else if (opt_type == 1)		/* number option */
5710 	{
5711 	    rettv->v_type = VAR_NUMBER;
5712 	    rettv->vval.v_number = numval;
5713 	}
5714 	else				/* string option */
5715 	{
5716 	    rettv->v_type = VAR_STRING;
5717 	    rettv->vval.v_string = stringval;
5718 	}
5719     }
5720     else if (working && (opt_type == -2 || opt_type == -1))
5721 	ret = FAIL;
5722 
5723     *option_end = c;		    /* put back for error messages */
5724     *arg = option_end;
5725 
5726     return ret;
5727 }
5728 
5729 /*
5730  * Allocate a variable for a string constant.
5731  * Return OK or FAIL.
5732  */
5733     static int
5734 get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
5735 {
5736     char_u	*p;
5737     char_u	*name;
5738     int		extra = 0;
5739 
5740     /*
5741      * Find the end of the string, skipping backslashed characters.
5742      */
5743     for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p))
5744     {
5745 	if (*p == '\\' && p[1] != NUL)
5746 	{
5747 	    ++p;
5748 	    /* A "\<x>" form occupies at least 4 characters, and produces up
5749 	     * to 6 characters: reserve space for 2 extra */
5750 	    if (*p == '<')
5751 		extra += 2;
5752 	}
5753     }
5754 
5755     if (*p != '"')
5756     {
5757 	EMSG2(_("E114: Missing quote: %s"), *arg);
5758 	return FAIL;
5759     }
5760 
5761     /* If only parsing, set *arg and return here */
5762     if (!evaluate)
5763     {
5764 	*arg = p + 1;
5765 	return OK;
5766     }
5767 
5768     /*
5769      * Copy the string into allocated memory, handling backslashed
5770      * characters.
5771      */
5772     name = alloc((unsigned)(p - *arg + extra));
5773     if (name == NULL)
5774 	return FAIL;
5775     rettv->v_type = VAR_STRING;
5776     rettv->vval.v_string = name;
5777 
5778     for (p = *arg + 1; *p != NUL && *p != '"'; )
5779     {
5780 	if (*p == '\\')
5781 	{
5782 	    switch (*++p)
5783 	    {
5784 		case 'b': *name++ = BS; ++p; break;
5785 		case 'e': *name++ = ESC; ++p; break;
5786 		case 'f': *name++ = FF; ++p; break;
5787 		case 'n': *name++ = NL; ++p; break;
5788 		case 'r': *name++ = CAR; ++p; break;
5789 		case 't': *name++ = TAB; ++p; break;
5790 
5791 		case 'X': /* hex: "\x1", "\x12" */
5792 		case 'x':
5793 		case 'u': /* Unicode: "\u0023" */
5794 		case 'U':
5795 			  if (vim_isxdigit(p[1]))
5796 			  {
5797 			      int	n, nr;
5798 			      int	c = toupper(*p);
5799 
5800 			      if (c == 'X')
5801 				  n = 2;
5802 			      else if (*p == 'u')
5803 				  n = 4;
5804 			      else
5805 				  n = 8;
5806 			      nr = 0;
5807 			      while (--n >= 0 && vim_isxdigit(p[1]))
5808 			      {
5809 				  ++p;
5810 				  nr = (nr << 4) + hex2nr(*p);
5811 			      }
5812 			      ++p;
5813 #ifdef FEAT_MBYTE
5814 			      /* For "\u" store the number according to
5815 			       * 'encoding'. */
5816 			      if (c != 'X')
5817 				  name += (*mb_char2bytes)(nr, name);
5818 			      else
5819 #endif
5820 				  *name++ = nr;
5821 			  }
5822 			  break;
5823 
5824 			  /* octal: "\1", "\12", "\123" */
5825 		case '0':
5826 		case '1':
5827 		case '2':
5828 		case '3':
5829 		case '4':
5830 		case '5':
5831 		case '6':
5832 		case '7': *name = *p++ - '0';
5833 			  if (*p >= '0' && *p <= '7')
5834 			  {
5835 			      *name = (*name << 3) + *p++ - '0';
5836 			      if (*p >= '0' && *p <= '7')
5837 				  *name = (*name << 3) + *p++ - '0';
5838 			  }
5839 			  ++name;
5840 			  break;
5841 
5842 			    /* Special key, e.g.: "\<C-W>" */
5843 		case '<': extra = trans_special(&p, name, TRUE);
5844 			  if (extra != 0)
5845 			  {
5846 			      name += extra;
5847 			      break;
5848 			  }
5849 			  /* FALLTHROUGH */
5850 
5851 		default:  MB_COPY_CHAR(p, name);
5852 			  break;
5853 	    }
5854 	}
5855 	else
5856 	    MB_COPY_CHAR(p, name);
5857 
5858     }
5859     *name = NUL;
5860     *arg = p + 1;
5861 
5862     return OK;
5863 }
5864 
5865 /*
5866  * Allocate a variable for a 'str''ing' constant.
5867  * Return OK or FAIL.
5868  */
5869     static int
5870 get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
5871 {
5872     char_u	*p;
5873     char_u	*str;
5874     int		reduce = 0;
5875 
5876     /*
5877      * Find the end of the string, skipping ''.
5878      */
5879     for (p = *arg + 1; *p != NUL; mb_ptr_adv(p))
5880     {
5881 	if (*p == '\'')
5882 	{
5883 	    if (p[1] != '\'')
5884 		break;
5885 	    ++reduce;
5886 	    ++p;
5887 	}
5888     }
5889 
5890     if (*p != '\'')
5891     {
5892 	EMSG2(_("E115: Missing quote: %s"), *arg);
5893 	return FAIL;
5894     }
5895 
5896     /* If only parsing return after setting "*arg" */
5897     if (!evaluate)
5898     {
5899 	*arg = p + 1;
5900 	return OK;
5901     }
5902 
5903     /*
5904      * Copy the string into allocated memory, handling '' to ' reduction.
5905      */
5906     str = alloc((unsigned)((p - *arg) - reduce));
5907     if (str == NULL)
5908 	return FAIL;
5909     rettv->v_type = VAR_STRING;
5910     rettv->vval.v_string = str;
5911 
5912     for (p = *arg + 1; *p != NUL; )
5913     {
5914 	if (*p == '\'')
5915 	{
5916 	    if (p[1] != '\'')
5917 		break;
5918 	    ++p;
5919 	}
5920 	MB_COPY_CHAR(p, str);
5921     }
5922     *str = NUL;
5923     *arg = p + 1;
5924 
5925     return OK;
5926 }
5927 
5928 /*
5929  * Allocate a variable for a List and fill it from "*arg".
5930  * Return OK or FAIL.
5931  */
5932     static int
5933 get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
5934 {
5935     list_T	*l = NULL;
5936     typval_T	tv;
5937     listitem_T	*item;
5938 
5939     if (evaluate)
5940     {
5941 	l = list_alloc();
5942 	if (l == NULL)
5943 	    return FAIL;
5944     }
5945 
5946     *arg = skipwhite(*arg + 1);
5947     while (**arg != ']' && **arg != NUL)
5948     {
5949 	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
5950 	    goto failret;
5951 	if (evaluate)
5952 	{
5953 	    item = listitem_alloc();
5954 	    if (item != NULL)
5955 	    {
5956 		item->li_tv = tv;
5957 		item->li_tv.v_lock = 0;
5958 		list_append(l, item);
5959 	    }
5960 	    else
5961 		clear_tv(&tv);
5962 	}
5963 
5964 	if (**arg == ']')
5965 	    break;
5966 	if (**arg != ',')
5967 	{
5968 	    EMSG2(_("E696: Missing comma in List: %s"), *arg);
5969 	    goto failret;
5970 	}
5971 	*arg = skipwhite(*arg + 1);
5972     }
5973 
5974     if (**arg != ']')
5975     {
5976 	EMSG2(_("E697: Missing end of List ']': %s"), *arg);
5977 failret:
5978 	if (evaluate)
5979 	    list_free(l, TRUE);
5980 	return FAIL;
5981     }
5982 
5983     *arg = skipwhite(*arg + 1);
5984     if (evaluate)
5985     {
5986 	rettv->v_type = VAR_LIST;
5987 	rettv->vval.v_list = l;
5988 	++l->lv_refcount;
5989     }
5990 
5991     return OK;
5992 }
5993 
5994 /*
5995  * Allocate an empty header for a list.
5996  * Caller should take care of the reference count.
5997  */
5998     list_T *
5999 list_alloc(void)
6000 {
6001     list_T  *l;
6002 
6003     l = (list_T *)alloc_clear(sizeof(list_T));
6004     if (l != NULL)
6005     {
6006 	/* Prepend the list to the list of lists for garbage collection. */
6007 	if (first_list != NULL)
6008 	    first_list->lv_used_prev = l;
6009 	l->lv_used_prev = NULL;
6010 	l->lv_used_next = first_list;
6011 	first_list = l;
6012     }
6013     return l;
6014 }
6015 
6016 /*
6017  * Allocate an empty list for a return value.
6018  * Returns OK or FAIL.
6019  */
6020     int
6021 rettv_list_alloc(typval_T *rettv)
6022 {
6023     list_T	*l = list_alloc();
6024 
6025     if (l == NULL)
6026 	return FAIL;
6027 
6028     rettv->vval.v_list = l;
6029     rettv->v_type = VAR_LIST;
6030     ++l->lv_refcount;
6031     return OK;
6032 }
6033 
6034 /*
6035  * Unreference a list: decrement the reference count and free it when it
6036  * becomes zero.
6037  */
6038     void
6039 list_unref(list_T *l)
6040 {
6041     if (l != NULL && --l->lv_refcount <= 0)
6042 	list_free(l, TRUE);
6043 }
6044 
6045 /*
6046  * Free a list, including all non-container items it points to.
6047  * Ignores the reference count.
6048  */
6049     void
6050 list_free(
6051     list_T  *l,
6052     int	    recurse)	/* Free Lists and Dictionaries recursively. */
6053 {
6054     listitem_T *item;
6055 
6056     /* Remove the list from the list of lists for garbage collection. */
6057     if (l->lv_used_prev == NULL)
6058 	first_list = l->lv_used_next;
6059     else
6060 	l->lv_used_prev->lv_used_next = l->lv_used_next;
6061     if (l->lv_used_next != NULL)
6062 	l->lv_used_next->lv_used_prev = l->lv_used_prev;
6063 
6064     for (item = l->lv_first; item != NULL; item = l->lv_first)
6065     {
6066 	/* Remove the item before deleting it. */
6067 	l->lv_first = item->li_next;
6068 	if (recurse || (item->li_tv.v_type != VAR_LIST
6069 					   && item->li_tv.v_type != VAR_DICT))
6070 	    clear_tv(&item->li_tv);
6071 	vim_free(item);
6072     }
6073     vim_free(l);
6074 }
6075 
6076 /*
6077  * Allocate a list item.
6078  * It is not initialized, don't forget to set v_lock.
6079  */
6080     listitem_T *
6081 listitem_alloc(void)
6082 {
6083     return (listitem_T *)alloc(sizeof(listitem_T));
6084 }
6085 
6086 /*
6087  * Free a list item.  Also clears the value.  Does not notify watchers.
6088  */
6089     void
6090 listitem_free(listitem_T *item)
6091 {
6092     clear_tv(&item->li_tv);
6093     vim_free(item);
6094 }
6095 
6096 /*
6097  * Remove a list item from a List and free it.  Also clears the value.
6098  */
6099     void
6100 listitem_remove(list_T *l, listitem_T *item)
6101 {
6102     vimlist_remove(l, item, item);
6103     listitem_free(item);
6104 }
6105 
6106 /*
6107  * Get the number of items in a list.
6108  */
6109     static long
6110 list_len(list_T *l)
6111 {
6112     if (l == NULL)
6113 	return 0L;
6114     return l->lv_len;
6115 }
6116 
6117 /*
6118  * Return TRUE when two lists have exactly the same values.
6119  */
6120     static int
6121 list_equal(
6122     list_T	*l1,
6123     list_T	*l2,
6124     int		ic,	/* ignore case for strings */
6125     int		recursive)  /* TRUE when used recursively */
6126 {
6127     listitem_T	*item1, *item2;
6128 
6129     if (l1 == NULL || l2 == NULL)
6130 	return FALSE;
6131     if (l1 == l2)
6132 	return TRUE;
6133     if (list_len(l1) != list_len(l2))
6134 	return FALSE;
6135 
6136     for (item1 = l1->lv_first, item2 = l2->lv_first;
6137 	    item1 != NULL && item2 != NULL;
6138 			       item1 = item1->li_next, item2 = item2->li_next)
6139 	if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive))
6140 	    return FALSE;
6141     return item1 == NULL && item2 == NULL;
6142 }
6143 
6144 /*
6145  * Return the dictitem that an entry in a hashtable points to.
6146  */
6147     dictitem_T *
6148 dict_lookup(hashitem_T *hi)
6149 {
6150     return HI2DI(hi);
6151 }
6152 
6153 /*
6154  * Return TRUE when two dictionaries have exactly the same key/values.
6155  */
6156     static int
6157 dict_equal(
6158     dict_T	*d1,
6159     dict_T	*d2,
6160     int		ic,	/* ignore case for strings */
6161     int		recursive) /* TRUE when used recursively */
6162 {
6163     hashitem_T	*hi;
6164     dictitem_T	*item2;
6165     int		todo;
6166 
6167     if (d1 == NULL || d2 == NULL)
6168 	return FALSE;
6169     if (d1 == d2)
6170 	return TRUE;
6171     if (dict_len(d1) != dict_len(d2))
6172 	return FALSE;
6173 
6174     todo = (int)d1->dv_hashtab.ht_used;
6175     for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi)
6176     {
6177 	if (!HASHITEM_EMPTY(hi))
6178 	{
6179 	    item2 = dict_find(d2, hi->hi_key, -1);
6180 	    if (item2 == NULL)
6181 		return FALSE;
6182 	    if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive))
6183 		return FALSE;
6184 	    --todo;
6185 	}
6186     }
6187     return TRUE;
6188 }
6189 
6190 static int tv_equal_recurse_limit;
6191 
6192 /*
6193  * Return TRUE if "tv1" and "tv2" have the same value.
6194  * Compares the items just like "==" would compare them, but strings and
6195  * numbers are different.  Floats and numbers are also different.
6196  */
6197     static int
6198 tv_equal(
6199     typval_T *tv1,
6200     typval_T *tv2,
6201     int	     ic,	    /* ignore case */
6202     int	     recursive)	    /* TRUE when used recursively */
6203 {
6204     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
6205     char_u	*s1, *s2;
6206     static int  recursive_cnt = 0;	    /* catch recursive loops */
6207     int		r;
6208 
6209     /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */
6210     if ((tv1->v_type == VAR_FUNC
6211 		|| (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
6212 	    && (tv2->v_type == VAR_FUNC
6213 		|| (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
6214     {
6215 	s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
6216 					       : tv1->vval.v_partial->pt_name;
6217 	s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
6218 					       : tv2->vval.v_partial->pt_name;
6219 	return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0);
6220     }
6221 
6222     if (tv1->v_type != tv2->v_type)
6223 	return FALSE;
6224 
6225     /* Catch lists and dicts that have an endless loop by limiting
6226      * recursiveness to a limit.  We guess they are equal then.
6227      * A fixed limit has the problem of still taking an awful long time.
6228      * Reduce the limit every time running into it. That should work fine for
6229      * deeply linked structures that are not recursively linked and catch
6230      * recursiveness quickly. */
6231     if (!recursive)
6232 	tv_equal_recurse_limit = 1000;
6233     if (recursive_cnt >= tv_equal_recurse_limit)
6234     {
6235 	--tv_equal_recurse_limit;
6236 	return TRUE;
6237     }
6238 
6239     switch (tv1->v_type)
6240     {
6241 	case VAR_LIST:
6242 	    ++recursive_cnt;
6243 	    r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
6244 	    --recursive_cnt;
6245 	    return r;
6246 
6247 	case VAR_DICT:
6248 	    ++recursive_cnt;
6249 	    r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
6250 	    --recursive_cnt;
6251 	    return r;
6252 
6253 	case VAR_NUMBER:
6254 	    return tv1->vval.v_number == tv2->vval.v_number;
6255 
6256 	case VAR_STRING:
6257 	    s1 = get_tv_string_buf(tv1, buf1);
6258 	    s2 = get_tv_string_buf(tv2, buf2);
6259 	    return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
6260 
6261 	case VAR_SPECIAL:
6262 	    return tv1->vval.v_number == tv2->vval.v_number;
6263 
6264 	case VAR_FLOAT:
6265 #ifdef FEAT_FLOAT
6266 	    return tv1->vval.v_float == tv2->vval.v_float;
6267 #endif
6268 	case VAR_JOB:
6269 #ifdef FEAT_JOB_CHANNEL
6270 	    return tv1->vval.v_job == tv2->vval.v_job;
6271 #endif
6272 	case VAR_CHANNEL:
6273 #ifdef FEAT_JOB_CHANNEL
6274 	    return tv1->vval.v_channel == tv2->vval.v_channel;
6275 #endif
6276 	case VAR_FUNC:
6277 	case VAR_PARTIAL:
6278 	case VAR_UNKNOWN:
6279 	    break;
6280     }
6281 
6282     /* VAR_UNKNOWN can be the result of a invalid expression, let's say it
6283      * does not equal anything, not even itself. */
6284     return FALSE;
6285 }
6286 
6287 /*
6288  * Locate item with index "n" in list "l" and return it.
6289  * A negative index is counted from the end; -1 is the last item.
6290  * Returns NULL when "n" is out of range.
6291  */
6292     listitem_T *
6293 list_find(list_T *l, long n)
6294 {
6295     listitem_T	*item;
6296     long	idx;
6297 
6298     if (l == NULL)
6299 	return NULL;
6300 
6301     /* Negative index is relative to the end. */
6302     if (n < 0)
6303 	n = l->lv_len + n;
6304 
6305     /* Check for index out of range. */
6306     if (n < 0 || n >= l->lv_len)
6307 	return NULL;
6308 
6309     /* When there is a cached index may start search from there. */
6310     if (l->lv_idx_item != NULL)
6311     {
6312 	if (n < l->lv_idx / 2)
6313 	{
6314 	    /* closest to the start of the list */
6315 	    item = l->lv_first;
6316 	    idx = 0;
6317 	}
6318 	else if (n > (l->lv_idx + l->lv_len) / 2)
6319 	{
6320 	    /* closest to the end of the list */
6321 	    item = l->lv_last;
6322 	    idx = l->lv_len - 1;
6323 	}
6324 	else
6325 	{
6326 	    /* closest to the cached index */
6327 	    item = l->lv_idx_item;
6328 	    idx = l->lv_idx;
6329 	}
6330     }
6331     else
6332     {
6333 	if (n < l->lv_len / 2)
6334 	{
6335 	    /* closest to the start of the list */
6336 	    item = l->lv_first;
6337 	    idx = 0;
6338 	}
6339 	else
6340 	{
6341 	    /* closest to the end of the list */
6342 	    item = l->lv_last;
6343 	    idx = l->lv_len - 1;
6344 	}
6345     }
6346 
6347     while (n > idx)
6348     {
6349 	/* search forward */
6350 	item = item->li_next;
6351 	++idx;
6352     }
6353     while (n < idx)
6354     {
6355 	/* search backward */
6356 	item = item->li_prev;
6357 	--idx;
6358     }
6359 
6360     /* cache the used index */
6361     l->lv_idx = idx;
6362     l->lv_idx_item = item;
6363 
6364     return item;
6365 }
6366 
6367 /*
6368  * Get list item "l[idx]" as a number.
6369  */
6370     static long
6371 list_find_nr(
6372     list_T	*l,
6373     long	idx,
6374     int		*errorp)	/* set to TRUE when something wrong */
6375 {
6376     listitem_T	*li;
6377 
6378     li = list_find(l, idx);
6379     if (li == NULL)
6380     {
6381 	if (errorp != NULL)
6382 	    *errorp = TRUE;
6383 	return -1L;
6384     }
6385     return get_tv_number_chk(&li->li_tv, errorp);
6386 }
6387 
6388 /*
6389  * Get list item "l[idx - 1]" as a string.  Returns NULL for failure.
6390  */
6391     char_u *
6392 list_find_str(list_T *l, long idx)
6393 {
6394     listitem_T	*li;
6395 
6396     li = list_find(l, idx - 1);
6397     if (li == NULL)
6398     {
6399 	EMSGN(_(e_listidx), idx);
6400 	return NULL;
6401     }
6402     return get_tv_string(&li->li_tv);
6403 }
6404 
6405 /*
6406  * Locate "item" list "l" and return its index.
6407  * Returns -1 when "item" is not in the list.
6408  */
6409     static long
6410 list_idx_of_item(list_T *l, listitem_T *item)
6411 {
6412     long	idx = 0;
6413     listitem_T	*li;
6414 
6415     if (l == NULL)
6416 	return -1;
6417     idx = 0;
6418     for (li = l->lv_first; li != NULL && li != item; li = li->li_next)
6419 	++idx;
6420     if (li == NULL)
6421 	return -1;
6422     return idx;
6423 }
6424 
6425 /*
6426  * Append item "item" to the end of list "l".
6427  */
6428     void
6429 list_append(list_T *l, listitem_T *item)
6430 {
6431     if (l->lv_last == NULL)
6432     {
6433 	/* empty list */
6434 	l->lv_first = item;
6435 	l->lv_last = item;
6436 	item->li_prev = NULL;
6437     }
6438     else
6439     {
6440 	l->lv_last->li_next = item;
6441 	item->li_prev = l->lv_last;
6442 	l->lv_last = item;
6443     }
6444     ++l->lv_len;
6445     item->li_next = NULL;
6446 }
6447 
6448 /*
6449  * Append typval_T "tv" to the end of list "l".
6450  * Return FAIL when out of memory.
6451  */
6452     int
6453 list_append_tv(list_T *l, typval_T *tv)
6454 {
6455     listitem_T	*li = listitem_alloc();
6456 
6457     if (li == NULL)
6458 	return FAIL;
6459     copy_tv(tv, &li->li_tv);
6460     list_append(l, li);
6461     return OK;
6462 }
6463 
6464 /*
6465  * Add a dictionary to a list.  Used by getqflist().
6466  * Return FAIL when out of memory.
6467  */
6468     int
6469 list_append_dict(list_T *list, dict_T *dict)
6470 {
6471     listitem_T	*li = listitem_alloc();
6472 
6473     if (li == NULL)
6474 	return FAIL;
6475     li->li_tv.v_type = VAR_DICT;
6476     li->li_tv.v_lock = 0;
6477     li->li_tv.vval.v_dict = dict;
6478     list_append(list, li);
6479     ++dict->dv_refcount;
6480     return OK;
6481 }
6482 
6483 /*
6484  * Make a copy of "str" and append it as an item to list "l".
6485  * When "len" >= 0 use "str[len]".
6486  * Returns FAIL when out of memory.
6487  */
6488     int
6489 list_append_string(list_T *l, char_u *str, int len)
6490 {
6491     listitem_T *li = listitem_alloc();
6492 
6493     if (li == NULL)
6494 	return FAIL;
6495     list_append(l, li);
6496     li->li_tv.v_type = VAR_STRING;
6497     li->li_tv.v_lock = 0;
6498     if (str == NULL)
6499 	li->li_tv.vval.v_string = NULL;
6500     else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len)
6501 						 : vim_strsave(str))) == NULL)
6502 	return FAIL;
6503     return OK;
6504 }
6505 
6506 /*
6507  * Append "n" to list "l".
6508  * Returns FAIL when out of memory.
6509  */
6510     int
6511 list_append_number(list_T *l, varnumber_T n)
6512 {
6513     listitem_T	*li;
6514 
6515     li = listitem_alloc();
6516     if (li == NULL)
6517 	return FAIL;
6518     li->li_tv.v_type = VAR_NUMBER;
6519     li->li_tv.v_lock = 0;
6520     li->li_tv.vval.v_number = n;
6521     list_append(l, li);
6522     return OK;
6523 }
6524 
6525 /*
6526  * Insert typval_T "tv" in list "l" before "item".
6527  * If "item" is NULL append at the end.
6528  * Return FAIL when out of memory.
6529  */
6530     int
6531 list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
6532 {
6533     listitem_T	*ni = listitem_alloc();
6534 
6535     if (ni == NULL)
6536 	return FAIL;
6537     copy_tv(tv, &ni->li_tv);
6538     list_insert(l, ni, item);
6539     return OK;
6540 }
6541 
6542     void
6543 list_insert(list_T *l, listitem_T *ni, listitem_T *item)
6544 {
6545     if (item == NULL)
6546 	/* Append new item at end of list. */
6547 	list_append(l, ni);
6548     else
6549     {
6550 	/* Insert new item before existing item. */
6551 	ni->li_prev = item->li_prev;
6552 	ni->li_next = item;
6553 	if (item->li_prev == NULL)
6554 	{
6555 	    l->lv_first = ni;
6556 	    ++l->lv_idx;
6557 	}
6558 	else
6559 	{
6560 	    item->li_prev->li_next = ni;
6561 	    l->lv_idx_item = NULL;
6562 	}
6563 	item->li_prev = ni;
6564 	++l->lv_len;
6565     }
6566 }
6567 
6568 /*
6569  * Extend "l1" with "l2".
6570  * If "bef" is NULL append at the end, otherwise insert before this item.
6571  * Returns FAIL when out of memory.
6572  */
6573     static int
6574 list_extend(list_T *l1, list_T *l2, listitem_T *bef)
6575 {
6576     listitem_T	*item;
6577     int		todo = l2->lv_len;
6578 
6579     /* We also quit the loop when we have inserted the original item count of
6580      * the list, avoid a hang when we extend a list with itself. */
6581     for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next)
6582 	if (list_insert_tv(l1, &item->li_tv, bef) == FAIL)
6583 	    return FAIL;
6584     return OK;
6585 }
6586 
6587 /*
6588  * Concatenate lists "l1" and "l2" into a new list, stored in "tv".
6589  * Return FAIL when out of memory.
6590  */
6591     static int
6592 list_concat(list_T *l1, list_T *l2, typval_T *tv)
6593 {
6594     list_T	*l;
6595 
6596     if (l1 == NULL || l2 == NULL)
6597 	return FAIL;
6598 
6599     /* make a copy of the first list. */
6600     l = list_copy(l1, FALSE, 0);
6601     if (l == NULL)
6602 	return FAIL;
6603     tv->v_type = VAR_LIST;
6604     tv->vval.v_list = l;
6605 
6606     /* append all items from the second list */
6607     return list_extend(l, l2, NULL);
6608 }
6609 
6610 /*
6611  * Make a copy of list "orig".  Shallow if "deep" is FALSE.
6612  * The refcount of the new list is set to 1.
6613  * See item_copy() for "copyID".
6614  * Returns NULL when out of memory.
6615  */
6616     static list_T *
6617 list_copy(list_T *orig, int deep, int copyID)
6618 {
6619     list_T	*copy;
6620     listitem_T	*item;
6621     listitem_T	*ni;
6622 
6623     if (orig == NULL)
6624 	return NULL;
6625 
6626     copy = list_alloc();
6627     if (copy != NULL)
6628     {
6629 	if (copyID != 0)
6630 	{
6631 	    /* Do this before adding the items, because one of the items may
6632 	     * refer back to this list. */
6633 	    orig->lv_copyID = copyID;
6634 	    orig->lv_copylist = copy;
6635 	}
6636 	for (item = orig->lv_first; item != NULL && !got_int;
6637 							 item = item->li_next)
6638 	{
6639 	    ni = listitem_alloc();
6640 	    if (ni == NULL)
6641 		break;
6642 	    if (deep)
6643 	    {
6644 		if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL)
6645 		{
6646 		    vim_free(ni);
6647 		    break;
6648 		}
6649 	    }
6650 	    else
6651 		copy_tv(&item->li_tv, &ni->li_tv);
6652 	    list_append(copy, ni);
6653 	}
6654 	++copy->lv_refcount;
6655 	if (item != NULL)
6656 	{
6657 	    list_unref(copy);
6658 	    copy = NULL;
6659 	}
6660     }
6661 
6662     return copy;
6663 }
6664 
6665 /*
6666  * Remove items "item" to "item2" from list "l".
6667  * Does not free the listitem or the value!
6668  * This used to be called list_remove, but that conflicts with a Sun header
6669  * file.
6670  */
6671     void
6672 vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2)
6673 {
6674     listitem_T	*ip;
6675 
6676     /* notify watchers */
6677     for (ip = item; ip != NULL; ip = ip->li_next)
6678     {
6679 	--l->lv_len;
6680 	list_fix_watch(l, ip);
6681 	if (ip == item2)
6682 	    break;
6683     }
6684 
6685     if (item2->li_next == NULL)
6686 	l->lv_last = item->li_prev;
6687     else
6688 	item2->li_next->li_prev = item->li_prev;
6689     if (item->li_prev == NULL)
6690 	l->lv_first = item2->li_next;
6691     else
6692 	item->li_prev->li_next = item2->li_next;
6693     l->lv_idx_item = NULL;
6694 }
6695 
6696 /*
6697  * Return an allocated string with the string representation of a list.
6698  * May return NULL.
6699  */
6700     static char_u *
6701 list2string(typval_T *tv, int copyID)
6702 {
6703     garray_T	ga;
6704 
6705     if (tv->vval.v_list == NULL)
6706 	return NULL;
6707     ga_init2(&ga, (int)sizeof(char), 80);
6708     ga_append(&ga, '[');
6709     if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == FAIL)
6710     {
6711 	vim_free(ga.ga_data);
6712 	return NULL;
6713     }
6714     ga_append(&ga, ']');
6715     ga_append(&ga, NUL);
6716     return (char_u *)ga.ga_data;
6717 }
6718 
6719 typedef struct join_S {
6720     char_u	*s;
6721     char_u	*tofree;
6722 } join_T;
6723 
6724     static int
6725 list_join_inner(
6726     garray_T	*gap,		/* to store the result in */
6727     list_T	*l,
6728     char_u	*sep,
6729     int		echo_style,
6730     int		copyID,
6731     garray_T	*join_gap)	/* to keep each list item string */
6732 {
6733     int		i;
6734     join_T	*p;
6735     int		len;
6736     int		sumlen = 0;
6737     int		first = TRUE;
6738     char_u	*tofree;
6739     char_u	numbuf[NUMBUFLEN];
6740     listitem_T	*item;
6741     char_u	*s;
6742 
6743     /* Stringify each item in the list. */
6744     for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
6745     {
6746 	if (echo_style)
6747 	    s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
6748 	else
6749 	    s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
6750 	if (s == NULL)
6751 	    return FAIL;
6752 
6753 	len = (int)STRLEN(s);
6754 	sumlen += len;
6755 
6756 	(void)ga_grow(join_gap, 1);
6757 	p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++);
6758 	if (tofree != NULL || s != numbuf)
6759 	{
6760 	    p->s = s;
6761 	    p->tofree = tofree;
6762 	}
6763 	else
6764 	{
6765 	    p->s = vim_strnsave(s, len);
6766 	    p->tofree = p->s;
6767 	}
6768 
6769 	line_breakcheck();
6770 	if (did_echo_string_emsg)  /* recursion error, bail out */
6771 	    break;
6772     }
6773 
6774     /* Allocate result buffer with its total size, avoid re-allocation and
6775      * multiple copy operations.  Add 2 for a tailing ']' and NUL. */
6776     if (join_gap->ga_len >= 2)
6777 	sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1);
6778     if (ga_grow(gap, sumlen + 2) == FAIL)
6779 	return FAIL;
6780 
6781     for (i = 0; i < join_gap->ga_len && !got_int; ++i)
6782     {
6783 	if (first)
6784 	    first = FALSE;
6785 	else
6786 	    ga_concat(gap, sep);
6787 	p = ((join_T *)join_gap->ga_data) + i;
6788 
6789 	if (p->s != NULL)
6790 	    ga_concat(gap, p->s);
6791 	line_breakcheck();
6792     }
6793 
6794     return OK;
6795 }
6796 
6797 /*
6798  * Join list "l" into a string in "*gap", using separator "sep".
6799  * When "echo_style" is TRUE use String as echoed, otherwise as inside a List.
6800  * Return FAIL or OK.
6801  */
6802     static int
6803 list_join(
6804     garray_T	*gap,
6805     list_T	*l,
6806     char_u	*sep,
6807     int		echo_style,
6808     int		copyID)
6809 {
6810     garray_T	join_ga;
6811     int		retval;
6812     join_T	*p;
6813     int		i;
6814 
6815     if (l->lv_len < 1)
6816 	return OK; /* nothing to do */
6817     ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
6818     retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga);
6819 
6820     /* Dispose each item in join_ga. */
6821     if (join_ga.ga_data != NULL)
6822     {
6823 	p = (join_T *)join_ga.ga_data;
6824 	for (i = 0; i < join_ga.ga_len; ++i)
6825 	{
6826 	    vim_free(p->tofree);
6827 	    ++p;
6828 	}
6829 	ga_clear(&join_ga);
6830     }
6831 
6832     return retval;
6833 }
6834 
6835 /*
6836  * Return the next (unique) copy ID.
6837  * Used for serializing nested structures.
6838  */
6839     int
6840 get_copyID(void)
6841 {
6842     current_copyID += COPYID_INC;
6843     return current_copyID;
6844 }
6845 
6846 /*
6847  * Garbage collection for lists and dictionaries.
6848  *
6849  * We use reference counts to be able to free most items right away when they
6850  * are no longer used.  But for composite items it's possible that it becomes
6851  * unused while the reference count is > 0: When there is a recursive
6852  * reference.  Example:
6853  *	:let l = [1, 2, 3]
6854  *	:let d = {9: l}
6855  *	:let l[1] = d
6856  *
6857  * Since this is quite unusual we handle this with garbage collection: every
6858  * once in a while find out which lists and dicts are not referenced from any
6859  * variable.
6860  *
6861  * Here is a good reference text about garbage collection (refers to Python
6862  * but it applies to all reference-counting mechanisms):
6863  *	http://python.ca/nas/python/gc/
6864  */
6865 
6866 /*
6867  * Do garbage collection for lists and dicts.
6868  * Return TRUE if some memory was freed.
6869  */
6870     int
6871 garbage_collect(void)
6872 {
6873     int		copyID;
6874     int		abort = FALSE;
6875     buf_T	*buf;
6876     win_T	*wp;
6877     int		i;
6878     funccall_T	*fc, **pfc;
6879     int		did_free = FALSE;
6880     int		did_free_funccal = FALSE;
6881 #ifdef FEAT_WINDOWS
6882     tabpage_T	*tp;
6883 #endif
6884 
6885     /* Only do this once. */
6886     want_garbage_collect = FALSE;
6887     may_garbage_collect = FALSE;
6888     garbage_collect_at_exit = FALSE;
6889 
6890     /* We advance by two because we add one for items referenced through
6891      * previous_funccal. */
6892     copyID = get_copyID();
6893 
6894     /*
6895      * 1. Go through all accessible variables and mark all lists and dicts
6896      *    with copyID.
6897      */
6898 
6899     /* Don't free variables in the previous_funccal list unless they are only
6900      * referenced through previous_funccal.  This must be first, because if
6901      * the item is referenced elsewhere the funccal must not be freed. */
6902     for (fc = previous_funccal; fc != NULL; fc = fc->caller)
6903     {
6904 	abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1,
6905 									NULL);
6906 	abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1,
6907 									NULL);
6908     }
6909 
6910     /* script-local variables */
6911     for (i = 1; i <= ga_scripts.ga_len; ++i)
6912 	abort = abort || set_ref_in_ht(&SCRIPT_VARS(i), copyID, NULL);
6913 
6914     /* buffer-local variables */
6915     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
6916 	abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID,
6917 								  NULL, NULL);
6918 
6919     /* window-local variables */
6920     FOR_ALL_TAB_WINDOWS(tp, wp)
6921 	abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID,
6922 								  NULL, NULL);
6923 #ifdef FEAT_AUTOCMD
6924     if (aucmd_win != NULL)
6925 	abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID,
6926 								  NULL, NULL);
6927 #endif
6928 
6929 #ifdef FEAT_WINDOWS
6930     /* tabpage-local variables */
6931     for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
6932 	abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID,
6933 								  NULL, NULL);
6934 #endif
6935 
6936     /* global variables */
6937     abort = abort || set_ref_in_ht(&globvarht, copyID, NULL);
6938 
6939     /* function-local variables */
6940     for (fc = current_funccal; fc != NULL; fc = fc->caller)
6941     {
6942 	abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL);
6943 	abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL);
6944     }
6945 
6946     /* v: vars */
6947     abort = abort || set_ref_in_ht(&vimvarht, copyID, NULL);
6948 
6949 #ifdef FEAT_LUA
6950     abort = abort || set_ref_in_lua(copyID);
6951 #endif
6952 
6953 #ifdef FEAT_PYTHON
6954     abort = abort || set_ref_in_python(copyID);
6955 #endif
6956 
6957 #ifdef FEAT_PYTHON3
6958     abort = abort || set_ref_in_python3(copyID);
6959 #endif
6960 
6961 #ifdef FEAT_JOB_CHANNEL
6962     abort = abort || set_ref_in_channel(copyID);
6963 #endif
6964 
6965     if (!abort)
6966     {
6967 	/*
6968 	 * 2. Free lists and dictionaries that are not referenced.
6969 	 */
6970 	did_free = free_unref_items(copyID);
6971 
6972 	/*
6973 	 * 3. Check if any funccal can be freed now.
6974 	 */
6975 	for (pfc = &previous_funccal; *pfc != NULL; )
6976 	{
6977 	    if (can_free_funccal(*pfc, copyID))
6978 	    {
6979 		fc = *pfc;
6980 		*pfc = fc->caller;
6981 		free_funccal(fc, TRUE);
6982 		did_free = TRUE;
6983 		did_free_funccal = TRUE;
6984 	    }
6985 	    else
6986 		pfc = &(*pfc)->caller;
6987 	}
6988 	if (did_free_funccal)
6989 	    /* When a funccal was freed some more items might be garbage
6990 	     * collected, so run again. */
6991 	    (void)garbage_collect();
6992     }
6993     else if (p_verbose > 0)
6994     {
6995 	verb_msg((char_u *)_("Not enough memory to set references, garbage collection aborted!"));
6996     }
6997 
6998     return did_free;
6999 }
7000 
7001 /*
7002  * Free lists, dictionaries and jobs that are no longer referenced.
7003  */
7004     static int
7005 free_unref_items(int copyID)
7006 {
7007     dict_T	*dd, *dd_next;
7008     list_T	*ll, *ll_next;
7009     int		did_free = FALSE;
7010 
7011     /*
7012      * Go through the list of dicts and free items without the copyID.
7013      */
7014     for (dd = first_dict; dd != NULL; )
7015     {
7016 	dd_next = dd->dv_used_next;
7017 	if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
7018 	{
7019 	    /* Free the Dictionary and ordinary items it contains, but don't
7020 	     * recurse into Lists and Dictionaries, they will be in the list
7021 	     * of dicts or list of lists. */
7022 	    dict_free(dd, FALSE);
7023 	    did_free = TRUE;
7024 	}
7025 	dd = dd_next;
7026     }
7027 
7028     /*
7029      * Go through the list of lists and free items without the copyID.
7030      * But don't free a list that has a watcher (used in a for loop), these
7031      * are not referenced anywhere.
7032      */
7033     for (ll = first_list; ll != NULL; )
7034     {
7035 	ll_next = ll->lv_used_next;
7036 	if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
7037 						      && ll->lv_watch == NULL)
7038 	{
7039 	    /* Free the List and ordinary items it contains, but don't recurse
7040 	     * into Lists and Dictionaries, they will be in the list of dicts
7041 	     * or list of lists. */
7042 	    list_free(ll, FALSE);
7043 	    did_free = TRUE;
7044 	}
7045 	ll = ll_next;
7046     }
7047 
7048     return did_free;
7049 }
7050 
7051 /*
7052  * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
7053  * "list_stack" is used to add lists to be marked.  Can be NULL.
7054  *
7055  * Returns TRUE if setting references failed somehow.
7056  */
7057     int
7058 set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
7059 {
7060     int		todo;
7061     int		abort = FALSE;
7062     hashitem_T	*hi;
7063     hashtab_T	*cur_ht;
7064     ht_stack_T	*ht_stack = NULL;
7065     ht_stack_T	*tempitem;
7066 
7067     cur_ht = ht;
7068     for (;;)
7069     {
7070 	if (!abort)
7071 	{
7072 	    /* Mark each item in the hashtab.  If the item contains a hashtab
7073 	     * it is added to ht_stack, if it contains a list it is added to
7074 	     * list_stack. */
7075 	    todo = (int)cur_ht->ht_used;
7076 	    for (hi = cur_ht->ht_array; todo > 0; ++hi)
7077 		if (!HASHITEM_EMPTY(hi))
7078 		{
7079 		    --todo;
7080 		    abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID,
7081 						       &ht_stack, list_stack);
7082 		}
7083 	}
7084 
7085 	if (ht_stack == NULL)
7086 	    break;
7087 
7088 	/* take an item from the stack */
7089 	cur_ht = ht_stack->ht;
7090 	tempitem = ht_stack;
7091 	ht_stack = ht_stack->prev;
7092 	free(tempitem);
7093     }
7094 
7095     return abort;
7096 }
7097 
7098 /*
7099  * Mark all lists and dicts referenced through list "l" with "copyID".
7100  * "ht_stack" is used to add hashtabs to be marked.  Can be NULL.
7101  *
7102  * Returns TRUE if setting references failed somehow.
7103  */
7104     int
7105 set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack)
7106 {
7107     listitem_T	 *li;
7108     int		 abort = FALSE;
7109     list_T	 *cur_l;
7110     list_stack_T *list_stack = NULL;
7111     list_stack_T *tempitem;
7112 
7113     cur_l = l;
7114     for (;;)
7115     {
7116 	if (!abort)
7117 	    /* Mark each item in the list.  If the item contains a hashtab
7118 	     * it is added to ht_stack, if it contains a list it is added to
7119 	     * list_stack. */
7120 	    for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next)
7121 		abort = abort || set_ref_in_item(&li->li_tv, copyID,
7122 						       ht_stack, &list_stack);
7123 	if (list_stack == NULL)
7124 	    break;
7125 
7126 	/* take an item from the stack */
7127 	cur_l = list_stack->list;
7128 	tempitem = list_stack;
7129 	list_stack = list_stack->prev;
7130 	free(tempitem);
7131     }
7132 
7133     return abort;
7134 }
7135 
7136 /*
7137  * Mark all lists and dicts referenced through typval "tv" with "copyID".
7138  * "list_stack" is used to add lists to be marked.  Can be NULL.
7139  * "ht_stack" is used to add hashtabs to be marked.  Can be NULL.
7140  *
7141  * Returns TRUE if setting references failed somehow.
7142  */
7143     int
7144 set_ref_in_item(
7145     typval_T	    *tv,
7146     int		    copyID,
7147     ht_stack_T	    **ht_stack,
7148     list_stack_T    **list_stack)
7149 {
7150     dict_T	*dd;
7151     list_T	*ll;
7152     int		abort = FALSE;
7153 
7154     if (tv->v_type == VAR_DICT || tv->v_type == VAR_PARTIAL)
7155     {
7156 	if (tv->v_type == VAR_DICT)
7157 	    dd = tv->vval.v_dict;
7158 	else if (tv->vval.v_partial != NULL)
7159 	    dd = tv->vval.v_partial->pt_dict;
7160 	else
7161 	    dd = NULL;
7162 	if (dd != NULL && dd->dv_copyID != copyID)
7163 	{
7164 	    /* Didn't see this dict yet. */
7165 	    dd->dv_copyID = copyID;
7166 	    if (ht_stack == NULL)
7167 	    {
7168 		abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
7169 	    }
7170 	    else
7171 	    {
7172 		ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T));
7173 		if (newitem == NULL)
7174 		    abort = TRUE;
7175 		else
7176 		{
7177 		    newitem->ht = &dd->dv_hashtab;
7178 		    newitem->prev = *ht_stack;
7179 		    *ht_stack = newitem;
7180 		}
7181 	    }
7182 	}
7183     }
7184     else if (tv->v_type == VAR_LIST)
7185     {
7186 	ll = tv->vval.v_list;
7187 	if (ll != NULL && ll->lv_copyID != copyID)
7188 	{
7189 	    /* Didn't see this list yet. */
7190 	    ll->lv_copyID = copyID;
7191 	    if (list_stack == NULL)
7192 	    {
7193 		abort = set_ref_in_list(ll, copyID, ht_stack);
7194 	    }
7195 	    else
7196 	    {
7197 		list_stack_T *newitem = (list_stack_T*)malloc(
7198 							sizeof(list_stack_T));
7199 		if (newitem == NULL)
7200 		    abort = TRUE;
7201 		else
7202 		{
7203 		    newitem->list = ll;
7204 		    newitem->prev = *list_stack;
7205 		    *list_stack = newitem;
7206 		}
7207 	    }
7208 	}
7209     }
7210     return abort;
7211 }
7212 
7213     static void
7214 partial_free(partial_T *pt, int free_dict)
7215 {
7216     int i;
7217 
7218     for (i = 0; i < pt->pt_argc; ++i)
7219 	clear_tv(&pt->pt_argv[i]);
7220     vim_free(pt->pt_argv);
7221     if (free_dict)
7222 	dict_unref(pt->pt_dict);
7223     func_unref(pt->pt_name);
7224     vim_free(pt->pt_name);
7225     vim_free(pt);
7226 }
7227 
7228 /*
7229  * Unreference a closure: decrement the reference count and free it when it
7230  * becomes zero.
7231  */
7232     void
7233 partial_unref(partial_T *pt)
7234 {
7235     if (pt != NULL && --pt->pt_refcount <= 0)
7236 	partial_free(pt, TRUE);
7237 }
7238 
7239 /*
7240  * Allocate an empty header for a dictionary.
7241  */
7242     dict_T *
7243 dict_alloc(void)
7244 {
7245     dict_T *d;
7246 
7247     d = (dict_T *)alloc(sizeof(dict_T));
7248     if (d != NULL)
7249     {
7250 	/* Add the dict to the list of dicts for garbage collection. */
7251 	if (first_dict != NULL)
7252 	    first_dict->dv_used_prev = d;
7253 	d->dv_used_next = first_dict;
7254 	d->dv_used_prev = NULL;
7255 	first_dict = d;
7256 
7257 	hash_init(&d->dv_hashtab);
7258 	d->dv_lock = 0;
7259 	d->dv_scope = 0;
7260 	d->dv_refcount = 0;
7261 	d->dv_copyID = 0;
7262     }
7263     return d;
7264 }
7265 
7266 /*
7267  * Allocate an empty dict for a return value.
7268  * Returns OK or FAIL.
7269  */
7270     int
7271 rettv_dict_alloc(typval_T *rettv)
7272 {
7273     dict_T	*d = dict_alloc();
7274 
7275     if (d == NULL)
7276 	return FAIL;
7277 
7278     rettv->vval.v_dict = d;
7279     rettv->v_type = VAR_DICT;
7280     ++d->dv_refcount;
7281     return OK;
7282 }
7283 
7284 
7285 /*
7286  * Unreference a Dictionary: decrement the reference count and free it when it
7287  * becomes zero.
7288  */
7289     void
7290 dict_unref(dict_T *d)
7291 {
7292     if (d != NULL && --d->dv_refcount <= 0)
7293 	dict_free(d, TRUE);
7294 }
7295 
7296 /*
7297  * Free a Dictionary, including all non-container items it contains.
7298  * Ignores the reference count.
7299  */
7300     void
7301 dict_free(
7302     dict_T  *d,
7303     int	    recurse)	/* Free Lists and Dictionaries recursively. */
7304 {
7305     int		todo;
7306     hashitem_T	*hi;
7307     dictitem_T	*di;
7308 
7309     /* Remove the dict from the list of dicts for garbage collection. */
7310     if (d->dv_used_prev == NULL)
7311 	first_dict = d->dv_used_next;
7312     else
7313 	d->dv_used_prev->dv_used_next = d->dv_used_next;
7314     if (d->dv_used_next != NULL)
7315 	d->dv_used_next->dv_used_prev = d->dv_used_prev;
7316 
7317     /* Lock the hashtab, we don't want it to resize while freeing items. */
7318     hash_lock(&d->dv_hashtab);
7319     todo = (int)d->dv_hashtab.ht_used;
7320     for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
7321     {
7322 	if (!HASHITEM_EMPTY(hi))
7323 	{
7324 	    /* Remove the item before deleting it, just in case there is
7325 	     * something recursive causing trouble. */
7326 	    di = HI2DI(hi);
7327 	    hash_remove(&d->dv_hashtab, hi);
7328 	    if (recurse || (di->di_tv.v_type != VAR_LIST
7329 					     && di->di_tv.v_type != VAR_DICT))
7330 	    {
7331 		if (!recurse && di->di_tv.v_type == VAR_PARTIAL)
7332 		{
7333 		    partial_T *pt = di->di_tv.vval.v_partial;
7334 
7335 		    /* We unref the partial but not the dict it refers to. */
7336 		    if (pt != NULL && --pt->pt_refcount == 0)
7337 			partial_free(pt, FALSE);
7338 		}
7339 		else
7340 		    clear_tv(&di->di_tv);
7341 	    }
7342 	    vim_free(di);
7343 	    --todo;
7344 	}
7345     }
7346     hash_clear(&d->dv_hashtab);
7347     vim_free(d);
7348 }
7349 
7350 /*
7351  * Allocate a Dictionary item.
7352  * The "key" is copied to the new item.
7353  * Note that the value of the item "di_tv" still needs to be initialized!
7354  * Returns NULL when out of memory.
7355  */
7356     dictitem_T *
7357 dictitem_alloc(char_u *key)
7358 {
7359     dictitem_T *di;
7360 
7361     di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) + STRLEN(key)));
7362     if (di != NULL)
7363     {
7364 	STRCPY(di->di_key, key);
7365 	di->di_flags = DI_FLAGS_ALLOC;
7366     }
7367     return di;
7368 }
7369 
7370 /*
7371  * Make a copy of a Dictionary item.
7372  */
7373     static dictitem_T *
7374 dictitem_copy(dictitem_T *org)
7375 {
7376     dictitem_T *di;
7377 
7378     di = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
7379 						      + STRLEN(org->di_key)));
7380     if (di != NULL)
7381     {
7382 	STRCPY(di->di_key, org->di_key);
7383 	di->di_flags = DI_FLAGS_ALLOC;
7384 	copy_tv(&org->di_tv, &di->di_tv);
7385     }
7386     return di;
7387 }
7388 
7389 /*
7390  * Remove item "item" from Dictionary "dict" and free it.
7391  */
7392     static void
7393 dictitem_remove(dict_T *dict, dictitem_T *item)
7394 {
7395     hashitem_T	*hi;
7396 
7397     hi = hash_find(&dict->dv_hashtab, item->di_key);
7398     if (HASHITEM_EMPTY(hi))
7399 	EMSG2(_(e_intern2), "dictitem_remove()");
7400     else
7401 	hash_remove(&dict->dv_hashtab, hi);
7402     dictitem_free(item);
7403 }
7404 
7405 /*
7406  * Free a dict item.  Also clears the value.
7407  */
7408     void
7409 dictitem_free(dictitem_T *item)
7410 {
7411     clear_tv(&item->di_tv);
7412     if (item->di_flags & DI_FLAGS_ALLOC)
7413 	vim_free(item);
7414 }
7415 
7416 /*
7417  * Make a copy of dict "d".  Shallow if "deep" is FALSE.
7418  * The refcount of the new dict is set to 1.
7419  * See item_copy() for "copyID".
7420  * Returns NULL when out of memory.
7421  */
7422     static dict_T *
7423 dict_copy(dict_T *orig, int deep, int copyID)
7424 {
7425     dict_T	*copy;
7426     dictitem_T	*di;
7427     int		todo;
7428     hashitem_T	*hi;
7429 
7430     if (orig == NULL)
7431 	return NULL;
7432 
7433     copy = dict_alloc();
7434     if (copy != NULL)
7435     {
7436 	if (copyID != 0)
7437 	{
7438 	    orig->dv_copyID = copyID;
7439 	    orig->dv_copydict = copy;
7440 	}
7441 	todo = (int)orig->dv_hashtab.ht_used;
7442 	for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
7443 	{
7444 	    if (!HASHITEM_EMPTY(hi))
7445 	    {
7446 		--todo;
7447 
7448 		di = dictitem_alloc(hi->hi_key);
7449 		if (di == NULL)
7450 		    break;
7451 		if (deep)
7452 		{
7453 		    if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep,
7454 							      copyID) == FAIL)
7455 		    {
7456 			vim_free(di);
7457 			break;
7458 		    }
7459 		}
7460 		else
7461 		    copy_tv(&HI2DI(hi)->di_tv, &di->di_tv);
7462 		if (dict_add(copy, di) == FAIL)
7463 		{
7464 		    dictitem_free(di);
7465 		    break;
7466 		}
7467 	    }
7468 	}
7469 
7470 	++copy->dv_refcount;
7471 	if (todo > 0)
7472 	{
7473 	    dict_unref(copy);
7474 	    copy = NULL;
7475 	}
7476     }
7477 
7478     return copy;
7479 }
7480 
7481 /*
7482  * Add item "item" to Dictionary "d".
7483  * Returns FAIL when out of memory and when key already exists.
7484  */
7485     int
7486 dict_add(dict_T *d, dictitem_T *item)
7487 {
7488     return hash_add(&d->dv_hashtab, item->di_key);
7489 }
7490 
7491 /*
7492  * Add a number or string entry to dictionary "d".
7493  * When "str" is NULL use number "nr", otherwise use "str".
7494  * Returns FAIL when out of memory and when key already exists.
7495  */
7496     int
7497 dict_add_nr_str(
7498     dict_T	*d,
7499     char	*key,
7500     long	nr,
7501     char_u	*str)
7502 {
7503     dictitem_T	*item;
7504 
7505     item = dictitem_alloc((char_u *)key);
7506     if (item == NULL)
7507 	return FAIL;
7508     item->di_tv.v_lock = 0;
7509     if (str == NULL)
7510     {
7511 	item->di_tv.v_type = VAR_NUMBER;
7512 	item->di_tv.vval.v_number = nr;
7513     }
7514     else
7515     {
7516 	item->di_tv.v_type = VAR_STRING;
7517 	item->di_tv.vval.v_string = vim_strsave(str);
7518     }
7519     if (dict_add(d, item) == FAIL)
7520     {
7521 	dictitem_free(item);
7522 	return FAIL;
7523     }
7524     return OK;
7525 }
7526 
7527 /*
7528  * Add a list entry to dictionary "d".
7529  * Returns FAIL when out of memory and when key already exists.
7530  */
7531     int
7532 dict_add_list(dict_T *d, char *key, list_T *list)
7533 {
7534     dictitem_T	*item;
7535 
7536     item = dictitem_alloc((char_u *)key);
7537     if (item == NULL)
7538 	return FAIL;
7539     item->di_tv.v_lock = 0;
7540     item->di_tv.v_type = VAR_LIST;
7541     item->di_tv.vval.v_list = list;
7542     if (dict_add(d, item) == FAIL)
7543     {
7544 	dictitem_free(item);
7545 	return FAIL;
7546     }
7547     ++list->lv_refcount;
7548     return OK;
7549 }
7550 
7551 /*
7552  * Get the number of items in a Dictionary.
7553  */
7554     static long
7555 dict_len(dict_T *d)
7556 {
7557     if (d == NULL)
7558 	return 0L;
7559     return (long)d->dv_hashtab.ht_used;
7560 }
7561 
7562 /*
7563  * Find item "key[len]" in Dictionary "d".
7564  * If "len" is negative use strlen(key).
7565  * Returns NULL when not found.
7566  */
7567     dictitem_T *
7568 dict_find(dict_T *d, char_u *key, int len)
7569 {
7570 #define AKEYLEN 200
7571     char_u	buf[AKEYLEN];
7572     char_u	*akey;
7573     char_u	*tofree = NULL;
7574     hashitem_T	*hi;
7575 
7576     if (len < 0)
7577 	akey = key;
7578     else if (len >= AKEYLEN)
7579     {
7580 	tofree = akey = vim_strnsave(key, len);
7581 	if (akey == NULL)
7582 	    return NULL;
7583     }
7584     else
7585     {
7586 	/* Avoid a malloc/free by using buf[]. */
7587 	vim_strncpy(buf, key, len);
7588 	akey = buf;
7589     }
7590 
7591     hi = hash_find(&d->dv_hashtab, akey);
7592     vim_free(tofree);
7593     if (HASHITEM_EMPTY(hi))
7594 	return NULL;
7595     return HI2DI(hi);
7596 }
7597 
7598 /*
7599  * Get a string item from a dictionary.
7600  * When "save" is TRUE allocate memory for it.
7601  * Returns NULL if the entry doesn't exist or out of memory.
7602  */
7603     char_u *
7604 get_dict_string(dict_T *d, char_u *key, int save)
7605 {
7606     dictitem_T	*di;
7607     char_u	*s;
7608 
7609     di = dict_find(d, key, -1);
7610     if (di == NULL)
7611 	return NULL;
7612     s = get_tv_string(&di->di_tv);
7613     if (save && s != NULL)
7614 	s = vim_strsave(s);
7615     return s;
7616 }
7617 
7618 /*
7619  * Get a number item from a dictionary.
7620  * Returns 0 if the entry doesn't exist.
7621  */
7622     long
7623 get_dict_number(dict_T *d, char_u *key)
7624 {
7625     dictitem_T	*di;
7626 
7627     di = dict_find(d, key, -1);
7628     if (di == NULL)
7629 	return 0;
7630     return get_tv_number(&di->di_tv);
7631 }
7632 
7633 /*
7634  * Return an allocated string with the string representation of a Dictionary.
7635  * May return NULL.
7636  */
7637     static char_u *
7638 dict2string(typval_T *tv, int copyID)
7639 {
7640     garray_T	ga;
7641     int		first = TRUE;
7642     char_u	*tofree;
7643     char_u	numbuf[NUMBUFLEN];
7644     hashitem_T	*hi;
7645     char_u	*s;
7646     dict_T	*d;
7647     int		todo;
7648 
7649     if ((d = tv->vval.v_dict) == NULL)
7650 	return NULL;
7651     ga_init2(&ga, (int)sizeof(char), 80);
7652     ga_append(&ga, '{');
7653 
7654     todo = (int)d->dv_hashtab.ht_used;
7655     for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
7656     {
7657 	if (!HASHITEM_EMPTY(hi))
7658 	{
7659 	    --todo;
7660 
7661 	    if (first)
7662 		first = FALSE;
7663 	    else
7664 		ga_concat(&ga, (char_u *)", ");
7665 
7666 	    tofree = string_quote(hi->hi_key, FALSE);
7667 	    if (tofree != NULL)
7668 	    {
7669 		ga_concat(&ga, tofree);
7670 		vim_free(tofree);
7671 	    }
7672 	    ga_concat(&ga, (char_u *)": ");
7673 	    s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
7674 	    if (s != NULL)
7675 		ga_concat(&ga, s);
7676 	    vim_free(tofree);
7677 	    if (s == NULL || did_echo_string_emsg)
7678 		break;
7679 	    line_breakcheck();
7680 
7681 	}
7682     }
7683     if (todo > 0)
7684     {
7685 	vim_free(ga.ga_data);
7686 	return NULL;
7687     }
7688 
7689     ga_append(&ga, '}');
7690     ga_append(&ga, NUL);
7691     return (char_u *)ga.ga_data;
7692 }
7693 
7694 /*
7695  * Allocate a variable for a Dictionary and fill it from "*arg".
7696  * Return OK or FAIL.  Returns NOTDONE for {expr}.
7697  */
7698     static int
7699 get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
7700 {
7701     dict_T	*d = NULL;
7702     typval_T	tvkey;
7703     typval_T	tv;
7704     char_u	*key = NULL;
7705     dictitem_T	*item;
7706     char_u	*start = skipwhite(*arg + 1);
7707     char_u	buf[NUMBUFLEN];
7708 
7709     /*
7710      * First check if it's not a curly-braces thing: {expr}.
7711      * Must do this without evaluating, otherwise a function may be called
7712      * twice.  Unfortunately this means we need to call eval1() twice for the
7713      * first item.
7714      * But {} is an empty Dictionary.
7715      */
7716     if (*start != '}')
7717     {
7718 	if (eval1(&start, &tv, FALSE) == FAIL)	/* recursive! */
7719 	    return FAIL;
7720 	if (*start == '}')
7721 	    return NOTDONE;
7722     }
7723 
7724     if (evaluate)
7725     {
7726 	d = dict_alloc();
7727 	if (d == NULL)
7728 	    return FAIL;
7729     }
7730     tvkey.v_type = VAR_UNKNOWN;
7731     tv.v_type = VAR_UNKNOWN;
7732 
7733     *arg = skipwhite(*arg + 1);
7734     while (**arg != '}' && **arg != NUL)
7735     {
7736 	if (eval1(arg, &tvkey, evaluate) == FAIL)	/* recursive! */
7737 	    goto failret;
7738 	if (**arg != ':')
7739 	{
7740 	    EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg);
7741 	    clear_tv(&tvkey);
7742 	    goto failret;
7743 	}
7744 	if (evaluate)
7745 	{
7746 	    key = get_tv_string_buf_chk(&tvkey, buf);
7747 	    if (key == NULL || *key == NUL)
7748 	    {
7749 		/* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
7750 		if (key != NULL)
7751 		    EMSG(_(e_emptykey));
7752 		clear_tv(&tvkey);
7753 		goto failret;
7754 	    }
7755 	}
7756 
7757 	*arg = skipwhite(*arg + 1);
7758 	if (eval1(arg, &tv, evaluate) == FAIL)	/* recursive! */
7759 	{
7760 	    if (evaluate)
7761 		clear_tv(&tvkey);
7762 	    goto failret;
7763 	}
7764 	if (evaluate)
7765 	{
7766 	    item = dict_find(d, key, -1);
7767 	    if (item != NULL)
7768 	    {
7769 		EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key);
7770 		clear_tv(&tvkey);
7771 		clear_tv(&tv);
7772 		goto failret;
7773 	    }
7774 	    item = dictitem_alloc(key);
7775 	    clear_tv(&tvkey);
7776 	    if (item != NULL)
7777 	    {
7778 		item->di_tv = tv;
7779 		item->di_tv.v_lock = 0;
7780 		if (dict_add(d, item) == FAIL)
7781 		    dictitem_free(item);
7782 	    }
7783 	}
7784 
7785 	if (**arg == '}')
7786 	    break;
7787 	if (**arg != ',')
7788 	{
7789 	    EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg);
7790 	    goto failret;
7791 	}
7792 	*arg = skipwhite(*arg + 1);
7793     }
7794 
7795     if (**arg != '}')
7796     {
7797 	EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg);
7798 failret:
7799 	if (evaluate)
7800 	    dict_free(d, TRUE);
7801 	return FAIL;
7802     }
7803 
7804     *arg = skipwhite(*arg + 1);
7805     if (evaluate)
7806     {
7807 	rettv->v_type = VAR_DICT;
7808 	rettv->vval.v_dict = d;
7809 	++d->dv_refcount;
7810     }
7811 
7812     return OK;
7813 }
7814 
7815 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
7816 #endif
7817 
7818     static char *
7819 get_var_special_name(int nr)
7820 {
7821     switch (nr)
7822     {
7823 	case VVAL_FALSE: return "v:false";
7824 	case VVAL_TRUE:  return "v:true";
7825 	case VVAL_NONE:  return "v:none";
7826 	case VVAL_NULL:  return "v:null";
7827     }
7828     EMSG2(_(e_intern2), "get_var_special_name()");
7829     return "42";
7830 }
7831 
7832 /*
7833  * Return a string with the string representation of a variable.
7834  * If the memory is allocated "tofree" is set to it, otherwise NULL.
7835  * "numbuf" is used for a number.
7836  * Does not put quotes around strings, as ":echo" displays values.
7837  * When "copyID" is not NULL replace recursive lists and dicts with "...".
7838  * May return NULL.
7839  */
7840     static char_u *
7841 echo_string(
7842     typval_T	*tv,
7843     char_u	**tofree,
7844     char_u	*numbuf,
7845     int		copyID)
7846 {
7847     static int	recurse = 0;
7848     char_u	*r = NULL;
7849 
7850     if (recurse >= DICT_MAXNEST)
7851     {
7852 	if (!did_echo_string_emsg)
7853 	{
7854 	    /* Only give this message once for a recursive call to avoid
7855 	     * flooding the user with errors.  And stop iterating over lists
7856 	     * and dicts. */
7857 	    did_echo_string_emsg = TRUE;
7858 	    EMSG(_("E724: variable nested too deep for displaying"));
7859 	}
7860 	*tofree = NULL;
7861 	return (char_u *)"{E724}";
7862     }
7863     ++recurse;
7864 
7865     switch (tv->v_type)
7866     {
7867 	case VAR_FUNC:
7868 	    *tofree = NULL;
7869 	    r = tv->vval.v_string;
7870 	    break;
7871 
7872 	case VAR_PARTIAL:
7873 	    {
7874 		partial_T   *pt = tv->vval.v_partial;
7875 		char_u	    *fname = string_quote(pt == NULL ? NULL
7876 							: pt->pt_name, FALSE);
7877 		garray_T    ga;
7878 		int	    i;
7879 		char_u	    *tf;
7880 
7881 		ga_init2(&ga, 1, 100);
7882 		ga_concat(&ga, (char_u *)"function(");
7883 		if (fname != NULL)
7884 		{
7885 		    ga_concat(&ga, fname);
7886 		    vim_free(fname);
7887 		}
7888 		if (pt != NULL && pt->pt_argc > 0)
7889 		{
7890 		    ga_concat(&ga, (char_u *)", [");
7891 		    for (i = 0; i < pt->pt_argc; ++i)
7892 		    {
7893 			if (i > 0)
7894 			    ga_concat(&ga, (char_u *)", ");
7895 			ga_concat(&ga,
7896 			     tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
7897 			vim_free(tf);
7898 		    }
7899 		    ga_concat(&ga, (char_u *)"]");
7900 		}
7901 		if (pt != NULL && pt->pt_dict != NULL)
7902 		{
7903 		    typval_T dtv;
7904 
7905 		    ga_concat(&ga, (char_u *)", ");
7906 		    dtv.v_type = VAR_DICT;
7907 		    dtv.vval.v_dict = pt->pt_dict;
7908 		    ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
7909 		    vim_free(tf);
7910 		}
7911 		ga_concat(&ga, (char_u *)")");
7912 
7913 		*tofree = ga.ga_data;
7914 		r = *tofree;
7915 		break;
7916 	    }
7917 
7918 	case VAR_LIST:
7919 	    if (tv->vval.v_list == NULL)
7920 	    {
7921 		*tofree = NULL;
7922 		r = NULL;
7923 	    }
7924 	    else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID)
7925 	    {
7926 		*tofree = NULL;
7927 		r = (char_u *)"[...]";
7928 	    }
7929 	    else
7930 	    {
7931 		tv->vval.v_list->lv_copyID = copyID;
7932 		*tofree = list2string(tv, copyID);
7933 		r = *tofree;
7934 	    }
7935 	    break;
7936 
7937 	case VAR_DICT:
7938 	    if (tv->vval.v_dict == NULL)
7939 	    {
7940 		*tofree = NULL;
7941 		r = NULL;
7942 	    }
7943 	    else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID)
7944 	    {
7945 		*tofree = NULL;
7946 		r = (char_u *)"{...}";
7947 	    }
7948 	    else
7949 	    {
7950 		tv->vval.v_dict->dv_copyID = copyID;
7951 		*tofree = dict2string(tv, copyID);
7952 		r = *tofree;
7953 	    }
7954 	    break;
7955 
7956 	case VAR_STRING:
7957 	case VAR_NUMBER:
7958 	case VAR_UNKNOWN:
7959 	case VAR_JOB:
7960 	case VAR_CHANNEL:
7961 	    *tofree = NULL;
7962 	    r = get_tv_string_buf(tv, numbuf);
7963 	    break;
7964 
7965 	case VAR_FLOAT:
7966 #ifdef FEAT_FLOAT
7967 	    *tofree = NULL;
7968 	    vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv->vval.v_float);
7969 	    r = numbuf;
7970 	    break;
7971 #endif
7972 
7973 	case VAR_SPECIAL:
7974 	    *tofree = NULL;
7975 	    r = (char_u *)get_var_special_name(tv->vval.v_number);
7976 	    break;
7977     }
7978 
7979     if (--recurse == 0)
7980 	did_echo_string_emsg = FALSE;
7981     return r;
7982 }
7983 
7984 /*
7985  * Return a string with the string representation of a variable.
7986  * If the memory is allocated "tofree" is set to it, otherwise NULL.
7987  * "numbuf" is used for a number.
7988  * Puts quotes around strings, so that they can be parsed back by eval().
7989  * May return NULL.
7990  */
7991     static char_u *
7992 tv2string(
7993     typval_T	*tv,
7994     char_u	**tofree,
7995     char_u	*numbuf,
7996     int		copyID)
7997 {
7998     switch (tv->v_type)
7999     {
8000 	case VAR_FUNC:
8001 	    *tofree = string_quote(tv->vval.v_string, TRUE);
8002 	    return *tofree;
8003 	case VAR_STRING:
8004 	    *tofree = string_quote(tv->vval.v_string, FALSE);
8005 	    return *tofree;
8006 	case VAR_FLOAT:
8007 #ifdef FEAT_FLOAT
8008 	    *tofree = NULL;
8009 	    vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float);
8010 	    return numbuf;
8011 #endif
8012 	case VAR_NUMBER:
8013 	case VAR_LIST:
8014 	case VAR_DICT:
8015 	case VAR_PARTIAL:
8016 	case VAR_SPECIAL:
8017 	case VAR_JOB:
8018 	case VAR_CHANNEL:
8019 	case VAR_UNKNOWN:
8020 	    break;
8021     }
8022     return echo_string(tv, tofree, numbuf, copyID);
8023 }
8024 
8025 /*
8026  * Return string "str" in ' quotes, doubling ' characters.
8027  * If "str" is NULL an empty string is assumed.
8028  * If "function" is TRUE make it function('string').
8029  */
8030     static char_u *
8031 string_quote(char_u *str, int function)
8032 {
8033     unsigned	len;
8034     char_u	*p, *r, *s;
8035 
8036     len = (function ? 13 : 3);
8037     if (str != NULL)
8038     {
8039 	len += (unsigned)STRLEN(str);
8040 	for (p = str; *p != NUL; mb_ptr_adv(p))
8041 	    if (*p == '\'')
8042 		++len;
8043     }
8044     s = r = alloc(len);
8045     if (r != NULL)
8046     {
8047 	if (function)
8048 	{
8049 	    STRCPY(r, "function('");
8050 	    r += 10;
8051 	}
8052 	else
8053 	    *r++ = '\'';
8054 	if (str != NULL)
8055 	    for (p = str; *p != NUL; )
8056 	    {
8057 		if (*p == '\'')
8058 		    *r++ = '\'';
8059 		MB_COPY_CHAR(p, r);
8060 	    }
8061 	*r++ = '\'';
8062 	if (function)
8063 	    *r++ = ')';
8064 	*r++ = NUL;
8065     }
8066     return s;
8067 }
8068 
8069 #if defined(FEAT_FLOAT) || defined(PROTO)
8070 /*
8071  * Convert the string "text" to a floating point number.
8072  * This uses strtod().  setlocale(LC_NUMERIC, "C") has been used to make sure
8073  * this always uses a decimal point.
8074  * Returns the length of the text that was consumed.
8075  */
8076     int
8077 string2float(
8078     char_u	*text,
8079     float_T	*value)	    /* result stored here */
8080 {
8081     char	*s = (char *)text;
8082     float_T	f;
8083 
8084     f = strtod(s, &s);
8085     *value = f;
8086     return (int)((char_u *)s - text);
8087 }
8088 #endif
8089 
8090 /*
8091  * Get the value of an environment variable.
8092  * "arg" is pointing to the '$'.  It is advanced to after the name.
8093  * If the environment variable was not set, silently assume it is empty.
8094  * Return FAIL if the name is invalid.
8095  */
8096     static int
8097 get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
8098 {
8099     char_u	*string = NULL;
8100     int		len;
8101     int		cc;
8102     char_u	*name;
8103     int		mustfree = FALSE;
8104 
8105     ++*arg;
8106     name = *arg;
8107     len = get_env_len(arg);
8108     if (evaluate)
8109     {
8110 	if (len == 0)
8111 	    return FAIL; /* invalid empty name */
8112 
8113 	cc = name[len];
8114 	name[len] = NUL;
8115 	/* first try vim_getenv(), fast for normal environment vars */
8116 	string = vim_getenv(name, &mustfree);
8117 	if (string != NULL && *string != NUL)
8118 	{
8119 	    if (!mustfree)
8120 		string = vim_strsave(string);
8121 	}
8122 	else
8123 	{
8124 	    if (mustfree)
8125 		vim_free(string);
8126 
8127 	    /* next try expanding things like $VIM and ${HOME} */
8128 	    string = expand_env_save(name - 1);
8129 	    if (string != NULL && *string == '$')
8130 	    {
8131 		vim_free(string);
8132 		string = NULL;
8133 	    }
8134 	}
8135 	name[len] = cc;
8136 
8137 	rettv->v_type = VAR_STRING;
8138 	rettv->vval.v_string = string;
8139     }
8140 
8141     return OK;
8142 }
8143 
8144 /*
8145  * Array with names and number of arguments of all internal functions
8146  * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH!
8147  */
8148 static struct fst
8149 {
8150     char	*f_name;	/* function name */
8151     char	f_min_argc;	/* minimal number of arguments */
8152     char	f_max_argc;	/* maximal number of arguments */
8153     void	(*f_func)(typval_T *args, typval_T *rvar);
8154 				/* implementation of function */
8155 } functions[] =
8156 {
8157 #ifdef FEAT_FLOAT
8158     {"abs",		1, 1, f_abs},
8159     {"acos",		1, 1, f_acos},	/* WJMc */
8160 #endif
8161     {"add",		2, 2, f_add},
8162     {"alloc_fail",	3, 3, f_alloc_fail},
8163     {"and",		2, 2, f_and},
8164     {"append",		2, 2, f_append},
8165     {"argc",		0, 0, f_argc},
8166     {"argidx",		0, 0, f_argidx},
8167     {"arglistid",	0, 2, f_arglistid},
8168     {"argv",		0, 1, f_argv},
8169 #ifdef FEAT_FLOAT
8170     {"asin",		1, 1, f_asin},	/* WJMc */
8171 #endif
8172     {"assert_equal",	2, 3, f_assert_equal},
8173     {"assert_exception", 1, 2, f_assert_exception},
8174     {"assert_fails",	1, 2, f_assert_fails},
8175     {"assert_false",	1, 2, f_assert_false},
8176     {"assert_match",	2, 3, f_assert_match},
8177     {"assert_true",	1, 2, f_assert_true},
8178 #ifdef FEAT_FLOAT
8179     {"atan",		1, 1, f_atan},
8180     {"atan2",		2, 2, f_atan2},
8181 #endif
8182     {"browse",		4, 4, f_browse},
8183     {"browsedir",	2, 2, f_browsedir},
8184     {"bufexists",	1, 1, f_bufexists},
8185     {"buffer_exists",	1, 1, f_bufexists},	/* obsolete */
8186     {"buffer_name",	1, 1, f_bufname},	/* obsolete */
8187     {"buffer_number",	1, 1, f_bufnr},		/* obsolete */
8188     {"buflisted",	1, 1, f_buflisted},
8189     {"bufloaded",	1, 1, f_bufloaded},
8190     {"bufname",		1, 1, f_bufname},
8191     {"bufnr",		1, 2, f_bufnr},
8192     {"bufwinnr",	1, 1, f_bufwinnr},
8193     {"byte2line",	1, 1, f_byte2line},
8194     {"byteidx",		2, 2, f_byteidx},
8195     {"byteidxcomp",	2, 2, f_byteidxcomp},
8196     {"call",		2, 3, f_call},
8197 #ifdef FEAT_FLOAT
8198     {"ceil",		1, 1, f_ceil},
8199 #endif
8200 #ifdef FEAT_JOB_CHANNEL
8201     {"ch_close",	1, 1, f_ch_close},
8202     {"ch_evalexpr",	2, 3, f_ch_evalexpr},
8203     {"ch_evalraw",	2, 3, f_ch_evalraw},
8204     {"ch_getbufnr",	2, 2, f_ch_getbufnr},
8205     {"ch_getjob",	1, 1, f_ch_getjob},
8206     {"ch_info",		1, 1, f_ch_info},
8207     {"ch_log",		1, 2, f_ch_log},
8208     {"ch_logfile",	1, 2, f_ch_logfile},
8209     {"ch_open",		1, 2, f_ch_open},
8210     {"ch_read",		1, 2, f_ch_read},
8211     {"ch_readraw",	1, 2, f_ch_readraw},
8212     {"ch_sendexpr",	2, 3, f_ch_sendexpr},
8213     {"ch_sendraw",	2, 3, f_ch_sendraw},
8214     {"ch_setoptions",	2, 2, f_ch_setoptions},
8215     {"ch_status",	1, 1, f_ch_status},
8216 #endif
8217     {"changenr",	0, 0, f_changenr},
8218     {"char2nr",		1, 2, f_char2nr},
8219     {"cindent",		1, 1, f_cindent},
8220     {"clearmatches",	0, 0, f_clearmatches},
8221     {"col",		1, 1, f_col},
8222 #if defined(FEAT_INS_EXPAND)
8223     {"complete",	2, 2, f_complete},
8224     {"complete_add",	1, 1, f_complete_add},
8225     {"complete_check",	0, 0, f_complete_check},
8226 #endif
8227     {"confirm",		1, 4, f_confirm},
8228     {"copy",		1, 1, f_copy},
8229 #ifdef FEAT_FLOAT
8230     {"cos",		1, 1, f_cos},
8231     {"cosh",		1, 1, f_cosh},
8232 #endif
8233     {"count",		2, 4, f_count},
8234     {"cscope_connection",0,3, f_cscope_connection},
8235     {"cursor",		1, 3, f_cursor},
8236     {"deepcopy",	1, 2, f_deepcopy},
8237     {"delete",		1, 2, f_delete},
8238     {"did_filetype",	0, 0, f_did_filetype},
8239     {"diff_filler",	1, 1, f_diff_filler},
8240     {"diff_hlID",	2, 2, f_diff_hlID},
8241     {"disable_char_avail_for_testing", 1, 1, f_disable_char_avail_for_testing},
8242     {"empty",		1, 1, f_empty},
8243     {"escape",		2, 2, f_escape},
8244     {"eval",		1, 1, f_eval},
8245     {"eventhandler",	0, 0, f_eventhandler},
8246     {"executable",	1, 1, f_executable},
8247     {"exepath",		1, 1, f_exepath},
8248     {"exists",		1, 1, f_exists},
8249 #ifdef FEAT_FLOAT
8250     {"exp",		1, 1, f_exp},
8251 #endif
8252     {"expand",		1, 3, f_expand},
8253     {"extend",		2, 3, f_extend},
8254     {"feedkeys",	1, 2, f_feedkeys},
8255     {"file_readable",	1, 1, f_filereadable},	/* obsolete */
8256     {"filereadable",	1, 1, f_filereadable},
8257     {"filewritable",	1, 1, f_filewritable},
8258     {"filter",		2, 2, f_filter},
8259     {"finddir",		1, 3, f_finddir},
8260     {"findfile",	1, 3, f_findfile},
8261 #ifdef FEAT_FLOAT
8262     {"float2nr",	1, 1, f_float2nr},
8263     {"floor",		1, 1, f_floor},
8264     {"fmod",		2, 2, f_fmod},
8265 #endif
8266     {"fnameescape",	1, 1, f_fnameescape},
8267     {"fnamemodify",	2, 2, f_fnamemodify},
8268     {"foldclosed",	1, 1, f_foldclosed},
8269     {"foldclosedend",	1, 1, f_foldclosedend},
8270     {"foldlevel",	1, 1, f_foldlevel},
8271     {"foldtext",	0, 0, f_foldtext},
8272     {"foldtextresult",	1, 1, f_foldtextresult},
8273     {"foreground",	0, 0, f_foreground},
8274     {"function",	1, 3, f_function},
8275     {"garbagecollect",	0, 1, f_garbagecollect},
8276     {"get",		2, 3, f_get},
8277     {"getbufline",	2, 3, f_getbufline},
8278     {"getbufvar",	2, 3, f_getbufvar},
8279     {"getchar",		0, 1, f_getchar},
8280     {"getcharmod",	0, 0, f_getcharmod},
8281     {"getcharsearch",	0, 0, f_getcharsearch},
8282     {"getcmdline",	0, 0, f_getcmdline},
8283     {"getcmdpos",	0, 0, f_getcmdpos},
8284     {"getcmdtype",	0, 0, f_getcmdtype},
8285     {"getcmdwintype",	0, 0, f_getcmdwintype},
8286     {"getcurpos",	0, 0, f_getcurpos},
8287     {"getcwd",		0, 2, f_getcwd},
8288     {"getfontname",	0, 1, f_getfontname},
8289     {"getfperm",	1, 1, f_getfperm},
8290     {"getfsize",	1, 1, f_getfsize},
8291     {"getftime",	1, 1, f_getftime},
8292     {"getftype",	1, 1, f_getftype},
8293     {"getline",		1, 2, f_getline},
8294     {"getloclist",	1, 1, f_getqflist},
8295     {"getmatches",	0, 0, f_getmatches},
8296     {"getpid",		0, 0, f_getpid},
8297     {"getpos",		1, 1, f_getpos},
8298     {"getqflist",	0, 0, f_getqflist},
8299     {"getreg",		0, 3, f_getreg},
8300     {"getregtype",	0, 1, f_getregtype},
8301     {"gettabvar",	2, 3, f_gettabvar},
8302     {"gettabwinvar",	3, 4, f_gettabwinvar},
8303     {"getwinposx",	0, 0, f_getwinposx},
8304     {"getwinposy",	0, 0, f_getwinposy},
8305     {"getwinvar",	2, 3, f_getwinvar},
8306     {"glob",		1, 4, f_glob},
8307     {"glob2regpat",	1, 1, f_glob2regpat},
8308     {"globpath",	2, 5, f_globpath},
8309     {"has",		1, 1, f_has},
8310     {"has_key",		2, 2, f_has_key},
8311     {"haslocaldir",	0, 2, f_haslocaldir},
8312     {"hasmapto",	1, 3, f_hasmapto},
8313     {"highlightID",	1, 1, f_hlID},		/* obsolete */
8314     {"highlight_exists",1, 1, f_hlexists},	/* obsolete */
8315     {"histadd",		2, 2, f_histadd},
8316     {"histdel",		1, 2, f_histdel},
8317     {"histget",		1, 2, f_histget},
8318     {"histnr",		1, 1, f_histnr},
8319     {"hlID",		1, 1, f_hlID},
8320     {"hlexists",	1, 1, f_hlexists},
8321     {"hostname",	0, 0, f_hostname},
8322     {"iconv",		3, 3, f_iconv},
8323     {"indent",		1, 1, f_indent},
8324     {"index",		2, 4, f_index},
8325     {"input",		1, 3, f_input},
8326     {"inputdialog",	1, 3, f_inputdialog},
8327     {"inputlist",	1, 1, f_inputlist},
8328     {"inputrestore",	0, 0, f_inputrestore},
8329     {"inputsave",	0, 0, f_inputsave},
8330     {"inputsecret",	1, 2, f_inputsecret},
8331     {"insert",		2, 3, f_insert},
8332     {"invert",		1, 1, f_invert},
8333     {"isdirectory",	1, 1, f_isdirectory},
8334     {"islocked",	1, 1, f_islocked},
8335 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
8336     {"isnan",		1, 1, f_isnan},
8337 #endif
8338     {"items",		1, 1, f_items},
8339 #ifdef FEAT_JOB_CHANNEL
8340     {"job_getchannel",	1, 1, f_job_getchannel},
8341     {"job_info",	1, 1, f_job_info},
8342     {"job_setoptions",	2, 2, f_job_setoptions},
8343     {"job_start",	1, 2, f_job_start},
8344     {"job_status",	1, 1, f_job_status},
8345     {"job_stop",	1, 2, f_job_stop},
8346 #endif
8347     {"join",		1, 2, f_join},
8348     {"js_decode",	1, 1, f_js_decode},
8349     {"js_encode",	1, 1, f_js_encode},
8350     {"json_decode",	1, 1, f_json_decode},
8351     {"json_encode",	1, 1, f_json_encode},
8352     {"keys",		1, 1, f_keys},
8353     {"last_buffer_nr",	0, 0, f_last_buffer_nr},/* obsolete */
8354     {"len",		1, 1, f_len},
8355     {"libcall",		3, 3, f_libcall},
8356     {"libcallnr",	3, 3, f_libcallnr},
8357     {"line",		1, 1, f_line},
8358     {"line2byte",	1, 1, f_line2byte},
8359     {"lispindent",	1, 1, f_lispindent},
8360     {"localtime",	0, 0, f_localtime},
8361 #ifdef FEAT_FLOAT
8362     {"log",		1, 1, f_log},
8363     {"log10",		1, 1, f_log10},
8364 #endif
8365 #ifdef FEAT_LUA
8366     {"luaeval",		1, 2, f_luaeval},
8367 #endif
8368     {"map",		2, 2, f_map},
8369     {"maparg",		1, 4, f_maparg},
8370     {"mapcheck",	1, 3, f_mapcheck},
8371     {"match",		2, 4, f_match},
8372     {"matchadd",	2, 5, f_matchadd},
8373     {"matchaddpos",	2, 5, f_matchaddpos},
8374     {"matcharg",	1, 1, f_matcharg},
8375     {"matchdelete",	1, 1, f_matchdelete},
8376     {"matchend",	2, 4, f_matchend},
8377     {"matchlist",	2, 4, f_matchlist},
8378     {"matchstr",	2, 4, f_matchstr},
8379     {"max",		1, 1, f_max},
8380     {"min",		1, 1, f_min},
8381 #ifdef vim_mkdir
8382     {"mkdir",		1, 3, f_mkdir},
8383 #endif
8384     {"mode",		0, 1, f_mode},
8385 #ifdef FEAT_MZSCHEME
8386     {"mzeval",		1, 1, f_mzeval},
8387 #endif
8388     {"nextnonblank",	1, 1, f_nextnonblank},
8389     {"nr2char",		1, 2, f_nr2char},
8390     {"or",		2, 2, f_or},
8391     {"pathshorten",	1, 1, f_pathshorten},
8392 #ifdef FEAT_PERL
8393     {"perleval",	1, 1, f_perleval},
8394 #endif
8395 #ifdef FEAT_FLOAT
8396     {"pow",		2, 2, f_pow},
8397 #endif
8398     {"prevnonblank",	1, 1, f_prevnonblank},
8399     {"printf",		2, 19, f_printf},
8400     {"pumvisible",	0, 0, f_pumvisible},
8401 #ifdef FEAT_PYTHON3
8402     {"py3eval",		1, 1, f_py3eval},
8403 #endif
8404 #ifdef FEAT_PYTHON
8405     {"pyeval",		1, 1, f_pyeval},
8406 #endif
8407     {"range",		1, 3, f_range},
8408     {"readfile",	1, 3, f_readfile},
8409     {"reltime",		0, 2, f_reltime},
8410 #ifdef FEAT_FLOAT
8411     {"reltimefloat",	1, 1, f_reltimefloat},
8412 #endif
8413     {"reltimestr",	1, 1, f_reltimestr},
8414     {"remote_expr",	2, 3, f_remote_expr},
8415     {"remote_foreground", 1, 1, f_remote_foreground},
8416     {"remote_peek",	1, 2, f_remote_peek},
8417     {"remote_read",	1, 1, f_remote_read},
8418     {"remote_send",	2, 3, f_remote_send},
8419     {"remove",		2, 3, f_remove},
8420     {"rename",		2, 2, f_rename},
8421     {"repeat",		2, 2, f_repeat},
8422     {"resolve",		1, 1, f_resolve},
8423     {"reverse",		1, 1, f_reverse},
8424 #ifdef FEAT_FLOAT
8425     {"round",		1, 1, f_round},
8426 #endif
8427     {"screenattr",	2, 2, f_screenattr},
8428     {"screenchar",	2, 2, f_screenchar},
8429     {"screencol",	0, 0, f_screencol},
8430     {"screenrow",	0, 0, f_screenrow},
8431     {"search",		1, 4, f_search},
8432     {"searchdecl",	1, 3, f_searchdecl},
8433     {"searchpair",	3, 7, f_searchpair},
8434     {"searchpairpos",	3, 7, f_searchpairpos},
8435     {"searchpos",	1, 4, f_searchpos},
8436     {"server2client",	2, 2, f_server2client},
8437     {"serverlist",	0, 0, f_serverlist},
8438     {"setbufvar",	3, 3, f_setbufvar},
8439     {"setcharsearch",	1, 1, f_setcharsearch},
8440     {"setcmdpos",	1, 1, f_setcmdpos},
8441     {"setfperm",	2, 2, f_setfperm},
8442     {"setline",		2, 2, f_setline},
8443     {"setloclist",	2, 3, f_setloclist},
8444     {"setmatches",	1, 1, f_setmatches},
8445     {"setpos",		2, 2, f_setpos},
8446     {"setqflist",	1, 2, f_setqflist},
8447     {"setreg",		2, 3, f_setreg},
8448     {"settabvar",	3, 3, f_settabvar},
8449     {"settabwinvar",	4, 4, f_settabwinvar},
8450     {"setwinvar",	3, 3, f_setwinvar},
8451 #ifdef FEAT_CRYPT
8452     {"sha256",		1, 1, f_sha256},
8453 #endif
8454     {"shellescape",	1, 2, f_shellescape},
8455     {"shiftwidth",	0, 0, f_shiftwidth},
8456     {"simplify",	1, 1, f_simplify},
8457 #ifdef FEAT_FLOAT
8458     {"sin",		1, 1, f_sin},
8459     {"sinh",		1, 1, f_sinh},
8460 #endif
8461     {"sort",		1, 3, f_sort},
8462     {"soundfold",	1, 1, f_soundfold},
8463     {"spellbadword",	0, 1, f_spellbadword},
8464     {"spellsuggest",	1, 3, f_spellsuggest},
8465     {"split",		1, 3, f_split},
8466 #ifdef FEAT_FLOAT
8467     {"sqrt",		1, 1, f_sqrt},
8468     {"str2float",	1, 1, f_str2float},
8469 #endif
8470     {"str2nr",		1, 2, f_str2nr},
8471     {"strchars",	1, 2, f_strchars},
8472     {"strdisplaywidth",	1, 2, f_strdisplaywidth},
8473 #ifdef HAVE_STRFTIME
8474     {"strftime",	1, 2, f_strftime},
8475 #endif
8476     {"stridx",		2, 3, f_stridx},
8477     {"string",		1, 1, f_string},
8478     {"strlen",		1, 1, f_strlen},
8479     {"strpart",		2, 3, f_strpart},
8480     {"strridx",		2, 3, f_strridx},
8481     {"strtrans",	1, 1, f_strtrans},
8482     {"strwidth",	1, 1, f_strwidth},
8483     {"submatch",	1, 2, f_submatch},
8484     {"substitute",	4, 4, f_substitute},
8485     {"synID",		3, 3, f_synID},
8486     {"synIDattr",	2, 3, f_synIDattr},
8487     {"synIDtrans",	1, 1, f_synIDtrans},
8488     {"synconcealed",	2, 2, f_synconcealed},
8489     {"synstack",	2, 2, f_synstack},
8490     {"system",		1, 2, f_system},
8491     {"systemlist",	1, 2, f_systemlist},
8492     {"tabpagebuflist",	0, 1, f_tabpagebuflist},
8493     {"tabpagenr",	0, 1, f_tabpagenr},
8494     {"tabpagewinnr",	1, 2, f_tabpagewinnr},
8495     {"tagfiles",	0, 0, f_tagfiles},
8496     {"taglist",		1, 1, f_taglist},
8497 #ifdef FEAT_FLOAT
8498     {"tan",		1, 1, f_tan},
8499     {"tanh",		1, 1, f_tanh},
8500 #endif
8501     {"tempname",	0, 0, f_tempname},
8502     {"test",		1, 1, f_test},
8503 #ifdef FEAT_TIMERS
8504     {"timer_start",	2, 3, f_timer_start},
8505     {"timer_stop",	1, 1, f_timer_stop},
8506 #endif
8507     {"tolower",		1, 1, f_tolower},
8508     {"toupper",		1, 1, f_toupper},
8509     {"tr",		3, 3, f_tr},
8510 #ifdef FEAT_FLOAT
8511     {"trunc",		1, 1, f_trunc},
8512 #endif
8513     {"type",		1, 1, f_type},
8514     {"undofile",	1, 1, f_undofile},
8515     {"undotree",	0, 0, f_undotree},
8516     {"uniq",		1, 3, f_uniq},
8517     {"values",		1, 1, f_values},
8518     {"virtcol",		1, 1, f_virtcol},
8519     {"visualmode",	0, 1, f_visualmode},
8520     {"wildmenumode",	0, 0, f_wildmenumode},
8521     {"win_findbuf",	1, 1, f_win_findbuf},
8522     {"win_getid",	0, 2, f_win_getid},
8523     {"win_gotoid",	1, 1, f_win_gotoid},
8524     {"win_id2tabwin",	1, 1, f_win_id2tabwin},
8525     {"win_id2win",	1, 1, f_win_id2win},
8526     {"winbufnr",	1, 1, f_winbufnr},
8527     {"wincol",		0, 0, f_wincol},
8528     {"winheight",	1, 1, f_winheight},
8529     {"winline",		0, 0, f_winline},
8530     {"winnr",		0, 1, f_winnr},
8531     {"winrestcmd",	0, 0, f_winrestcmd},
8532     {"winrestview",	1, 1, f_winrestview},
8533     {"winsaveview",	0, 0, f_winsaveview},
8534     {"winwidth",	1, 1, f_winwidth},
8535     {"wordcount",	0, 0, f_wordcount},
8536     {"writefile",	2, 3, f_writefile},
8537     {"xor",		2, 2, f_xor},
8538 };
8539 
8540 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
8541 
8542 /*
8543  * Function given to ExpandGeneric() to obtain the list of internal
8544  * or user defined function names.
8545  */
8546     char_u *
8547 get_function_name(expand_T *xp, int idx)
8548 {
8549     static int	intidx = -1;
8550     char_u	*name;
8551 
8552     if (idx == 0)
8553 	intidx = -1;
8554     if (intidx < 0)
8555     {
8556 	name = get_user_func_name(xp, idx);
8557 	if (name != NULL)
8558 	    return name;
8559     }
8560     if (++intidx < (int)(sizeof(functions) / sizeof(struct fst)))
8561     {
8562 	STRCPY(IObuff, functions[intidx].f_name);
8563 	STRCAT(IObuff, "(");
8564 	if (functions[intidx].f_max_argc == 0)
8565 	    STRCAT(IObuff, ")");
8566 	return IObuff;
8567     }
8568 
8569     return NULL;
8570 }
8571 
8572 /*
8573  * Function given to ExpandGeneric() to obtain the list of internal or
8574  * user defined variable or function names.
8575  */
8576     char_u *
8577 get_expr_name(expand_T *xp, int idx)
8578 {
8579     static int	intidx = -1;
8580     char_u	*name;
8581 
8582     if (idx == 0)
8583 	intidx = -1;
8584     if (intidx < 0)
8585     {
8586 	name = get_function_name(xp, idx);
8587 	if (name != NULL)
8588 	    return name;
8589     }
8590     return get_user_var_name(xp, ++intidx);
8591 }
8592 
8593 #endif /* FEAT_CMDL_COMPL */
8594 
8595 #if defined(EBCDIC) || defined(PROTO)
8596 /*
8597  * Compare struct fst by function name.
8598  */
8599     static int
8600 compare_func_name(const void *s1, const void *s2)
8601 {
8602     struct fst *p1 = (struct fst *)s1;
8603     struct fst *p2 = (struct fst *)s2;
8604 
8605     return STRCMP(p1->f_name, p2->f_name);
8606 }
8607 
8608 /*
8609  * Sort the function table by function name.
8610  * The sorting of the table above is ASCII dependant.
8611  * On machines using EBCDIC we have to sort it.
8612  */
8613     static void
8614 sortFunctions(void)
8615 {
8616     int		funcCnt = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
8617 
8618     qsort(functions, (size_t)funcCnt, sizeof(struct fst), compare_func_name);
8619 }
8620 #endif
8621 
8622 
8623 /*
8624  * Find internal function in table above.
8625  * Return index, or -1 if not found
8626  */
8627     static int
8628 find_internal_func(
8629     char_u	*name)		/* name of the function */
8630 {
8631     int		first = 0;
8632     int		last = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
8633     int		cmp;
8634     int		x;
8635 
8636     /*
8637      * Find the function name in the table. Binary search.
8638      */
8639     while (first <= last)
8640     {
8641 	x = first + ((unsigned)(last - first) >> 1);
8642 	cmp = STRCMP(name, functions[x].f_name);
8643 	if (cmp < 0)
8644 	    last = x - 1;
8645 	else if (cmp > 0)
8646 	    first = x + 1;
8647 	else
8648 	    return x;
8649     }
8650     return -1;
8651 }
8652 
8653 /*
8654  * Check if "name" is a variable of type VAR_FUNC.  If so, return the function
8655  * name it contains, otherwise return "name".
8656  * If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set
8657  * "partialp".
8658  */
8659     static char_u *
8660 deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload)
8661 {
8662     dictitem_T	*v;
8663     int		cc;
8664 
8665     if (partialp != NULL)
8666 	*partialp = NULL;
8667 
8668     cc = name[*lenp];
8669     name[*lenp] = NUL;
8670     v = find_var(name, NULL, no_autoload);
8671     name[*lenp] = cc;
8672     if (v != NULL && v->di_tv.v_type == VAR_FUNC)
8673     {
8674 	if (v->di_tv.vval.v_string == NULL)
8675 	{
8676 	    *lenp = 0;
8677 	    return (char_u *)"";	/* just in case */
8678 	}
8679 	*lenp = (int)STRLEN(v->di_tv.vval.v_string);
8680 	return v->di_tv.vval.v_string;
8681     }
8682 
8683     if (v != NULL && v->di_tv.v_type == VAR_PARTIAL)
8684     {
8685 	partial_T *pt = v->di_tv.vval.v_partial;
8686 
8687 	if (pt == NULL)
8688 	{
8689 	    *lenp = 0;
8690 	    return (char_u *)"";	/* just in case */
8691 	}
8692 	if (partialp != NULL)
8693 	    *partialp = pt;
8694 	*lenp = (int)STRLEN(pt->pt_name);
8695 	return pt->pt_name;
8696     }
8697 
8698     return name;
8699 }
8700 
8701 /*
8702  * Allocate a variable for the result of a function.
8703  * Return OK or FAIL.
8704  */
8705     static int
8706 get_func_tv(
8707     char_u	*name,		/* name of the function */
8708     int		len,		/* length of "name" */
8709     typval_T	*rettv,
8710     char_u	**arg,		/* argument, pointing to the '(' */
8711     linenr_T	firstline,	/* first line of range */
8712     linenr_T	lastline,	/* last line of range */
8713     int		*doesrange,	/* return: function handled range */
8714     int		evaluate,
8715     partial_T	*partial,	/* for extra arguments */
8716     dict_T	*selfdict)	/* Dictionary for "self" */
8717 {
8718     char_u	*argp;
8719     int		ret = OK;
8720     typval_T	argvars[MAX_FUNC_ARGS + 1];	/* vars for arguments */
8721     int		argcount = 0;		/* number of arguments found */
8722 
8723     /*
8724      * Get the arguments.
8725      */
8726     argp = *arg;
8727     while (argcount < MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc))
8728     {
8729 	argp = skipwhite(argp + 1);	    /* skip the '(' or ',' */
8730 	if (*argp == ')' || *argp == ',' || *argp == NUL)
8731 	    break;
8732 	if (eval1(&argp, &argvars[argcount], evaluate) == FAIL)
8733 	{
8734 	    ret = FAIL;
8735 	    break;
8736 	}
8737 	++argcount;
8738 	if (*argp != ',')
8739 	    break;
8740     }
8741     if (*argp == ')')
8742 	++argp;
8743     else
8744 	ret = FAIL;
8745 
8746     if (ret == OK)
8747 	ret = call_func(name, len, rettv, argcount, argvars,
8748 		 firstline, lastline, doesrange, evaluate, partial, selfdict);
8749     else if (!aborting())
8750     {
8751 	if (argcount == MAX_FUNC_ARGS)
8752 	    emsg_funcname(N_("E740: Too many arguments for function %s"), name);
8753 	else
8754 	    emsg_funcname(N_("E116: Invalid arguments for function %s"), name);
8755     }
8756 
8757     while (--argcount >= 0)
8758 	clear_tv(&argvars[argcount]);
8759 
8760     *arg = skipwhite(argp);
8761     return ret;
8762 }
8763 
8764 #define ERROR_UNKNOWN	0
8765 #define ERROR_TOOMANY	1
8766 #define ERROR_TOOFEW	2
8767 #define ERROR_SCRIPT	3
8768 #define ERROR_DICT	4
8769 #define ERROR_NONE	5
8770 #define ERROR_OTHER	6
8771 #define FLEN_FIXED 40
8772 
8773 /*
8774  * In a script change <SID>name() and s:name() to K_SNR 123_name().
8775  * Change <SNR>123_name() to K_SNR 123_name().
8776  * Use "fname_buf[FLEN_FIXED + 1]" when it fits, otherwise allocate memory
8777  * (slow).
8778  */
8779     static char_u *
8780 fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error)
8781 {
8782     int		llen;
8783     char_u	*fname;
8784     int		i;
8785 
8786     llen = eval_fname_script(name);
8787     if (llen > 0)
8788     {
8789 	fname_buf[0] = K_SPECIAL;
8790 	fname_buf[1] = KS_EXTRA;
8791 	fname_buf[2] = (int)KE_SNR;
8792 	i = 3;
8793 	if (eval_fname_sid(name))	/* "<SID>" or "s:" */
8794 	{
8795 	    if (current_SID <= 0)
8796 		*error = ERROR_SCRIPT;
8797 	    else
8798 	    {
8799 		sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID);
8800 		i = (int)STRLEN(fname_buf);
8801 	    }
8802 	}
8803 	if (i + STRLEN(name + llen) < FLEN_FIXED)
8804 	{
8805 	    STRCPY(fname_buf + i, name + llen);
8806 	    fname = fname_buf;
8807 	}
8808 	else
8809 	{
8810 	    fname = alloc((unsigned)(i + STRLEN(name + llen) + 1));
8811 	    if (fname == NULL)
8812 		*error = ERROR_OTHER;
8813 	    else
8814 	    {
8815 		*tofree = fname;
8816 		mch_memmove(fname, fname_buf, (size_t)i);
8817 		STRCPY(fname + i, name + llen);
8818 	    }
8819 	}
8820     }
8821     else
8822 	fname = name;
8823     return fname;
8824 }
8825 
8826 /*
8827  * Call a function with its resolved parameters
8828  * Return FAIL when the function can't be called,  OK otherwise.
8829  * Also returns OK when an error was encountered while executing the function.
8830  */
8831     int
8832 call_func(
8833     char_u	*funcname,	/* name of the function */
8834     int		len,		/* length of "name" */
8835     typval_T	*rettv,		/* return value goes here */
8836     int		argcount_in,	/* number of "argvars" */
8837     typval_T	*argvars_in,	/* vars for arguments, must have "argcount"
8838 				   PLUS ONE elements! */
8839     linenr_T	firstline,	/* first line of range */
8840     linenr_T	lastline,	/* last line of range */
8841     int		*doesrange,	/* return: function handled range */
8842     int		evaluate,
8843     partial_T	*partial,	/* optional, can be NULL */
8844     dict_T	*selfdict_in)	/* Dictionary for "self" */
8845 {
8846     int		ret = FAIL;
8847     int		error = ERROR_NONE;
8848     int		i;
8849     ufunc_T	*fp;
8850     char_u	fname_buf[FLEN_FIXED + 1];
8851     char_u	*tofree = NULL;
8852     char_u	*fname;
8853     char_u	*name;
8854     int		argcount = argcount_in;
8855     typval_T	*argvars = argvars_in;
8856     dict_T	*selfdict = selfdict_in;
8857     typval_T	argv[MAX_FUNC_ARGS + 1]; /* used when "partial" is not NULL */
8858     int		argv_clear = 0;
8859 
8860     /* Make a copy of the name, if it comes from a funcref variable it could
8861      * be changed or deleted in the called function. */
8862     name = vim_strnsave(funcname, len);
8863     if (name == NULL)
8864 	return ret;
8865 
8866     fname = fname_trans_sid(name, fname_buf, &tofree, &error);
8867 
8868     *doesrange = FALSE;
8869 
8870     if (partial != NULL)
8871     {
8872 	if (partial->pt_dict != NULL)
8873 	{
8874 	    /* When the function has a partial with a dict and there is a dict
8875 	     * argument, use the dict argument.  That is backwards compatible.
8876 	     */
8877 	    if (selfdict_in == NULL)
8878 		selfdict = partial->pt_dict;
8879 	}
8880 	if (error == ERROR_NONE && partial->pt_argc > 0)
8881 	{
8882 	    for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear)
8883 		copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]);
8884 	    for (i = 0; i < argcount_in; ++i)
8885 		argv[i + argv_clear] = argvars_in[i];
8886 	    argvars = argv;
8887 	    argcount = partial->pt_argc + argcount_in;
8888 	}
8889     }
8890 
8891 
8892     /* execute the function if no errors detected and executing */
8893     if (evaluate && error == ERROR_NONE)
8894     {
8895 	char_u *rfname = fname;
8896 
8897 	/* Ignore "g:" before a function name. */
8898 	if (fname[0] == 'g' && fname[1] == ':')
8899 	    rfname = fname + 2;
8900 
8901 	rettv->v_type = VAR_NUMBER;	/* default rettv is number zero */
8902 	rettv->vval.v_number = 0;
8903 	error = ERROR_UNKNOWN;
8904 
8905 	if (!builtin_function(rfname, -1))
8906 	{
8907 	    /*
8908 	     * User defined function.
8909 	     */
8910 	    fp = find_func(rfname);
8911 
8912 #ifdef FEAT_AUTOCMD
8913 	    /* Trigger FuncUndefined event, may load the function. */
8914 	    if (fp == NULL
8915 		    && apply_autocmds(EVENT_FUNCUNDEFINED,
8916 						     rfname, rfname, TRUE, NULL)
8917 		    && !aborting())
8918 	    {
8919 		/* executed an autocommand, search for the function again */
8920 		fp = find_func(rfname);
8921 	    }
8922 #endif
8923 	    /* Try loading a package. */
8924 	    if (fp == NULL && script_autoload(rfname, TRUE) && !aborting())
8925 	    {
8926 		/* loaded a package, search for the function again */
8927 		fp = find_func(rfname);
8928 	    }
8929 
8930 	    if (fp != NULL)
8931 	    {
8932 		if (fp->uf_flags & FC_RANGE)
8933 		    *doesrange = TRUE;
8934 		if (argcount < fp->uf_args.ga_len)
8935 		    error = ERROR_TOOFEW;
8936 		else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len)
8937 		    error = ERROR_TOOMANY;
8938 		else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
8939 		    error = ERROR_DICT;
8940 		else
8941 		{
8942 		    int did_save_redo = FALSE;
8943 
8944 		    /*
8945 		     * Call the user function.
8946 		     * Save and restore search patterns, script variables and
8947 		     * redo buffer.
8948 		     */
8949 		    save_search_patterns();
8950 #ifdef FEAT_INS_EXPAND
8951 		    if (!ins_compl_active())
8952 #endif
8953 		    {
8954 			saveRedobuff();
8955 			did_save_redo = TRUE;
8956 		    }
8957 		    ++fp->uf_calls;
8958 		    call_user_func(fp, argcount, argvars, rettv,
8959 					       firstline, lastline,
8960 				  (fp->uf_flags & FC_DICT) ? selfdict : NULL);
8961 		    if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name)
8962 						      && fp->uf_refcount <= 0)
8963 			/* Function was unreferenced while being used, free it
8964 			 * now. */
8965 			func_free(fp);
8966 		    if (did_save_redo)
8967 			restoreRedobuff();
8968 		    restore_search_patterns();
8969 		    error = ERROR_NONE;
8970 		}
8971 	    }
8972 	}
8973 	else
8974 	{
8975 	    /*
8976 	     * Find the function name in the table, call its implementation.
8977 	     */
8978 	    i = find_internal_func(fname);
8979 	    if (i >= 0)
8980 	    {
8981 		if (argcount < functions[i].f_min_argc)
8982 		    error = ERROR_TOOFEW;
8983 		else if (argcount > functions[i].f_max_argc)
8984 		    error = ERROR_TOOMANY;
8985 		else
8986 		{
8987 		    argvars[argcount].v_type = VAR_UNKNOWN;
8988 		    functions[i].f_func(argvars, rettv);
8989 		    error = ERROR_NONE;
8990 		}
8991 	    }
8992 	}
8993 	/*
8994 	 * The function call (or "FuncUndefined" autocommand sequence) might
8995 	 * have been aborted by an error, an interrupt, or an explicitly thrown
8996 	 * exception that has not been caught so far.  This situation can be
8997 	 * tested for by calling aborting().  For an error in an internal
8998 	 * function or for the "E132" error in call_user_func(), however, the
8999 	 * throw point at which the "force_abort" flag (temporarily reset by
9000 	 * emsg()) is normally updated has not been reached yet. We need to
9001 	 * update that flag first to make aborting() reliable.
9002 	 */
9003 	update_force_abort();
9004     }
9005     if (error == ERROR_NONE)
9006 	ret = OK;
9007 
9008     /*
9009      * Report an error unless the argument evaluation or function call has been
9010      * cancelled due to an aborting error, an interrupt, or an exception.
9011      */
9012     if (!aborting())
9013     {
9014 	switch (error)
9015 	{
9016 	    case ERROR_UNKNOWN:
9017 		    emsg_funcname(N_("E117: Unknown function: %s"), name);
9018 		    break;
9019 	    case ERROR_TOOMANY:
9020 		    emsg_funcname(e_toomanyarg, name);
9021 		    break;
9022 	    case ERROR_TOOFEW:
9023 		    emsg_funcname(N_("E119: Not enough arguments for function: %s"),
9024 									name);
9025 		    break;
9026 	    case ERROR_SCRIPT:
9027 		    emsg_funcname(N_("E120: Using <SID> not in a script context: %s"),
9028 									name);
9029 		    break;
9030 	    case ERROR_DICT:
9031 		    emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"),
9032 									name);
9033 		    break;
9034 	}
9035     }
9036 
9037     while (argv_clear > 0)
9038 	clear_tv(&argv[--argv_clear]);
9039     vim_free(tofree);
9040     vim_free(name);
9041 
9042     return ret;
9043 }
9044 
9045 /*
9046  * Give an error message with a function name.  Handle <SNR> things.
9047  * "ermsg" is to be passed without translation, use N_() instead of _().
9048  */
9049     static void
9050 emsg_funcname(char *ermsg, char_u *name)
9051 {
9052     char_u	*p;
9053 
9054     if (*name == K_SPECIAL)
9055 	p = concat_str((char_u *)"<SNR>", name + 3);
9056     else
9057 	p = name;
9058     EMSG2(_(ermsg), p);
9059     if (p != name)
9060 	vim_free(p);
9061 }
9062 
9063 /*
9064  * Return TRUE for a non-zero Number and a non-empty String.
9065  */
9066     static int
9067 non_zero_arg(typval_T *argvars)
9068 {
9069     return ((argvars[0].v_type == VAR_NUMBER
9070 		&& argvars[0].vval.v_number != 0)
9071 	    || (argvars[0].v_type == VAR_STRING
9072 		&& argvars[0].vval.v_string != NULL
9073 		&& *argvars[0].vval.v_string != NUL));
9074 }
9075 
9076 /*********************************************
9077  * Implementation of the built-in functions
9078  */
9079 
9080 #ifdef FEAT_FLOAT
9081 static int get_float_arg(typval_T *argvars, float_T *f);
9082 
9083 /*
9084  * Get the float value of "argvars[0]" into "f".
9085  * Returns FAIL when the argument is not a Number or Float.
9086  */
9087     static int
9088 get_float_arg(typval_T *argvars, float_T *f)
9089 {
9090     if (argvars[0].v_type == VAR_FLOAT)
9091     {
9092 	*f = argvars[0].vval.v_float;
9093 	return OK;
9094     }
9095     if (argvars[0].v_type == VAR_NUMBER)
9096     {
9097 	*f = (float_T)argvars[0].vval.v_number;
9098 	return OK;
9099     }
9100     EMSG(_("E808: Number or Float required"));
9101     return FAIL;
9102 }
9103 
9104 /*
9105  * "abs(expr)" function
9106  */
9107     static void
9108 f_abs(typval_T *argvars, typval_T *rettv)
9109 {
9110     if (argvars[0].v_type == VAR_FLOAT)
9111     {
9112 	rettv->v_type = VAR_FLOAT;
9113 	rettv->vval.v_float = fabs(argvars[0].vval.v_float);
9114     }
9115     else
9116     {
9117 	varnumber_T	n;
9118 	int		error = FALSE;
9119 
9120 	n = get_tv_number_chk(&argvars[0], &error);
9121 	if (error)
9122 	    rettv->vval.v_number = -1;
9123 	else if (n > 0)
9124 	    rettv->vval.v_number = n;
9125 	else
9126 	    rettv->vval.v_number = -n;
9127     }
9128 }
9129 
9130 /*
9131  * "acos()" function
9132  */
9133     static void
9134 f_acos(typval_T *argvars, typval_T *rettv)
9135 {
9136     float_T	f = 0.0;
9137 
9138     rettv->v_type = VAR_FLOAT;
9139     if (get_float_arg(argvars, &f) == OK)
9140 	rettv->vval.v_float = acos(f);
9141     else
9142 	rettv->vval.v_float = 0.0;
9143 }
9144 #endif
9145 
9146 /*
9147  * "add(list, item)" function
9148  */
9149     static void
9150 f_add(typval_T *argvars, typval_T *rettv)
9151 {
9152     list_T	*l;
9153 
9154     rettv->vval.v_number = 1; /* Default: Failed */
9155     if (argvars[0].v_type == VAR_LIST)
9156     {
9157 	if ((l = argvars[0].vval.v_list) != NULL
9158 		&& !tv_check_lock(l->lv_lock,
9159 					 (char_u *)N_("add() argument"), TRUE)
9160 		&& list_append_tv(l, &argvars[1]) == OK)
9161 	    copy_tv(&argvars[0], rettv);
9162     }
9163     else
9164 	EMSG(_(e_listreq));
9165 }
9166 
9167 /*
9168  * "alloc_fail(id, countdown, repeat)" function
9169  */
9170     static void
9171 f_alloc_fail(typval_T *argvars, typval_T *rettv UNUSED)
9172 {
9173     if (argvars[0].v_type != VAR_NUMBER
9174 	    || argvars[0].vval.v_number <= 0
9175 	    || argvars[1].v_type != VAR_NUMBER
9176 	    || argvars[1].vval.v_number < 0
9177 	    || argvars[2].v_type != VAR_NUMBER)
9178 	EMSG(_(e_invarg));
9179     else
9180     {
9181 	alloc_fail_id = argvars[0].vval.v_number;
9182 	if (alloc_fail_id >= aid_last)
9183 	    EMSG(_(e_invarg));
9184 	alloc_fail_countdown = argvars[1].vval.v_number;
9185 	alloc_fail_repeat = argvars[2].vval.v_number;
9186 	did_outofmem_msg = FALSE;
9187     }
9188 }
9189 
9190 /*
9191  * "and(expr, expr)" function
9192  */
9193     static void
9194 f_and(typval_T *argvars, typval_T *rettv)
9195 {
9196     rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
9197 					& get_tv_number_chk(&argvars[1], NULL);
9198 }
9199 
9200 /*
9201  * "append(lnum, string/list)" function
9202  */
9203     static void
9204 f_append(typval_T *argvars, typval_T *rettv)
9205 {
9206     long	lnum;
9207     char_u	*line;
9208     list_T	*l = NULL;
9209     listitem_T	*li = NULL;
9210     typval_T	*tv;
9211     long	added = 0;
9212 
9213     /* When coming here from Insert mode, sync undo, so that this can be
9214      * undone separately from what was previously inserted. */
9215     if (u_sync_once == 2)
9216     {
9217 	u_sync_once = 1; /* notify that u_sync() was called */
9218 	u_sync(TRUE);
9219     }
9220 
9221     lnum = get_tv_lnum(argvars);
9222     if (lnum >= 0
9223 	    && lnum <= curbuf->b_ml.ml_line_count
9224 	    && u_save(lnum, lnum + 1) == OK)
9225     {
9226 	if (argvars[1].v_type == VAR_LIST)
9227 	{
9228 	    l = argvars[1].vval.v_list;
9229 	    if (l == NULL)
9230 		return;
9231 	    li = l->lv_first;
9232 	}
9233 	for (;;)
9234 	{
9235 	    if (l == NULL)
9236 		tv = &argvars[1];	/* append a string */
9237 	    else if (li == NULL)
9238 		break;			/* end of list */
9239 	    else
9240 		tv = &li->li_tv;	/* append item from list */
9241 	    line = get_tv_string_chk(tv);
9242 	    if (line == NULL)		/* type error */
9243 	    {
9244 		rettv->vval.v_number = 1;	/* Failed */
9245 		break;
9246 	    }
9247 	    ml_append(lnum + added, line, (colnr_T)0, FALSE);
9248 	    ++added;
9249 	    if (l == NULL)
9250 		break;
9251 	    li = li->li_next;
9252 	}
9253 
9254 	appended_lines_mark(lnum, added);
9255 	if (curwin->w_cursor.lnum > lnum)
9256 	    curwin->w_cursor.lnum += added;
9257     }
9258     else
9259 	rettv->vval.v_number = 1;	/* Failed */
9260 }
9261 
9262 /*
9263  * "argc()" function
9264  */
9265     static void
9266 f_argc(typval_T *argvars UNUSED, typval_T *rettv)
9267 {
9268     rettv->vval.v_number = ARGCOUNT;
9269 }
9270 
9271 /*
9272  * "argidx()" function
9273  */
9274     static void
9275 f_argidx(typval_T *argvars UNUSED, typval_T *rettv)
9276 {
9277     rettv->vval.v_number = curwin->w_arg_idx;
9278 }
9279 
9280 /*
9281  * "arglistid()" function
9282  */
9283     static void
9284 f_arglistid(typval_T *argvars, typval_T *rettv)
9285 {
9286     win_T	*wp;
9287 
9288     rettv->vval.v_number = -1;
9289     wp = find_tabwin(&argvars[0], &argvars[1]);
9290     if (wp != NULL)
9291 	rettv->vval.v_number = wp->w_alist->id;
9292 }
9293 
9294 /*
9295  * "argv(nr)" function
9296  */
9297     static void
9298 f_argv(typval_T *argvars, typval_T *rettv)
9299 {
9300     int		idx;
9301 
9302     if (argvars[0].v_type != VAR_UNKNOWN)
9303     {
9304 	idx = get_tv_number_chk(&argvars[0], NULL);
9305 	if (idx >= 0 && idx < ARGCOUNT)
9306 	    rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
9307 	else
9308 	    rettv->vval.v_string = NULL;
9309 	rettv->v_type = VAR_STRING;
9310     }
9311     else if (rettv_list_alloc(rettv) == OK)
9312 	for (idx = 0; idx < ARGCOUNT; ++idx)
9313 	    list_append_string(rettv->vval.v_list,
9314 					       alist_name(&ARGLIST[idx]), -1);
9315 }
9316 
9317 static void prepare_assert_error(garray_T*gap);
9318 static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, typval_T *got_tv, int is_match);
9319 static void assert_error(garray_T *gap);
9320 static void assert_bool(typval_T *argvars, int isTrue);
9321 
9322 /*
9323  * Prepare "gap" for an assert error and add the sourcing position.
9324  */
9325     static void
9326 prepare_assert_error(garray_T *gap)
9327 {
9328     char buf[NUMBUFLEN];
9329 
9330     ga_init2(gap, 1, 100);
9331     if (sourcing_name != NULL)
9332     {
9333 	ga_concat(gap, sourcing_name);
9334 	if (sourcing_lnum > 0)
9335 	    ga_concat(gap, (char_u *)" ");
9336     }
9337     if (sourcing_lnum > 0)
9338     {
9339 	sprintf(buf, "line %ld", (long)sourcing_lnum);
9340 	ga_concat(gap, (char_u *)buf);
9341     }
9342     if (sourcing_name != NULL || sourcing_lnum > 0)
9343 	ga_concat(gap, (char_u *)": ");
9344 }
9345 
9346 /*
9347  * Append "str" to "gap", escaping unprintable characters.
9348  * Changes NL to \n, CR to \r, etc.
9349  */
9350     static void
9351 ga_concat_esc(garray_T *gap, char_u *str)
9352 {
9353     char_u  *p;
9354     char_u  buf[NUMBUFLEN];
9355 
9356     if (str == NULL)
9357     {
9358 	ga_concat(gap, (char_u *)"NULL");
9359 	return;
9360     }
9361 
9362     for (p = str; *p != NUL; ++p)
9363 	switch (*p)
9364 	{
9365 	    case BS: ga_concat(gap, (char_u *)"\\b"); break;
9366 	    case ESC: ga_concat(gap, (char_u *)"\\e"); break;
9367 	    case FF: ga_concat(gap, (char_u *)"\\f"); break;
9368 	    case NL: ga_concat(gap, (char_u *)"\\n"); break;
9369 	    case TAB: ga_concat(gap, (char_u *)"\\t"); break;
9370 	    case CAR: ga_concat(gap, (char_u *)"\\r"); break;
9371 	    case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
9372 	    default:
9373 		if (*p < ' ')
9374 		{
9375 		    vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
9376 		    ga_concat(gap, buf);
9377 		}
9378 		else
9379 		    ga_append(gap, *p);
9380 		break;
9381 	}
9382 }
9383 
9384 /*
9385  * Fill "gap" with information about an assert error.
9386  */
9387     static void
9388 fill_assert_error(
9389     garray_T	*gap,
9390     typval_T	*opt_msg_tv,
9391     char_u      *exp_str,
9392     typval_T	*exp_tv,
9393     typval_T	*got_tv,
9394     int		is_match)
9395 {
9396     char_u	numbuf[NUMBUFLEN];
9397     char_u	*tofree;
9398 
9399     if (opt_msg_tv->v_type != VAR_UNKNOWN)
9400     {
9401 	ga_concat(gap, tv2string(opt_msg_tv, &tofree, numbuf, 0));
9402 	vim_free(tofree);
9403     }
9404     else
9405     {
9406 	if (is_match)
9407 	    ga_concat(gap, (char_u *)"Pattern ");
9408 	else
9409 	    ga_concat(gap, (char_u *)"Expected ");
9410 	if (exp_str == NULL)
9411 	{
9412 	    ga_concat_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0));
9413 	    vim_free(tofree);
9414 	}
9415 	else
9416 	    ga_concat_esc(gap, exp_str);
9417 	if (is_match)
9418 	    ga_concat(gap, (char_u *)" does not match ");
9419 	else
9420 	    ga_concat(gap, (char_u *)" but got ");
9421 	ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
9422 	vim_free(tofree);
9423     }
9424 }
9425 
9426 /*
9427  * Add an assert error to v:errors.
9428  */
9429     static void
9430 assert_error(garray_T *gap)
9431 {
9432     struct vimvar   *vp = &vimvars[VV_ERRORS];
9433 
9434     if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL)
9435 	/* Make sure v:errors is a list. */
9436 	set_vim_var_list(VV_ERRORS, list_alloc());
9437     list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len);
9438 }
9439 
9440 /*
9441  * "assert_equal(expected, actual[, msg])" function
9442  */
9443     static void
9444 f_assert_equal(typval_T *argvars, typval_T *rettv UNUSED)
9445 {
9446     garray_T	ga;
9447 
9448     if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE))
9449     {
9450 	prepare_assert_error(&ga);
9451 	fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
9452 								       FALSE);
9453 	assert_error(&ga);
9454 	ga_clear(&ga);
9455     }
9456 }
9457 
9458 /*
9459  * "assert_exception(string[, msg])" function
9460  */
9461     static void
9462 f_assert_exception(typval_T *argvars, typval_T *rettv UNUSED)
9463 {
9464     garray_T	ga;
9465     char	*error;
9466 
9467     error = (char *)get_tv_string_chk(&argvars[0]);
9468     if (vimvars[VV_EXCEPTION].vv_str == NULL)
9469     {
9470 	prepare_assert_error(&ga);
9471 	ga_concat(&ga, (char_u *)"v:exception is not set");
9472 	assert_error(&ga);
9473 	ga_clear(&ga);
9474     }
9475     else if (error != NULL
9476 	    && strstr((char *)vimvars[VV_EXCEPTION].vv_str, error) == NULL)
9477     {
9478 	prepare_assert_error(&ga);
9479 	fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
9480 					 &vimvars[VV_EXCEPTION].vv_tv, FALSE);
9481 	assert_error(&ga);
9482 	ga_clear(&ga);
9483     }
9484 }
9485 
9486 /*
9487  * "assert_fails(cmd [, error])" function
9488  */
9489     static void
9490 f_assert_fails(typval_T *argvars, typval_T *rettv UNUSED)
9491 {
9492     char_u	*cmd = get_tv_string_chk(&argvars[0]);
9493     garray_T	ga;
9494 
9495     called_emsg = FALSE;
9496     suppress_errthrow = TRUE;
9497     emsg_silent = TRUE;
9498     do_cmdline_cmd(cmd);
9499     if (!called_emsg)
9500     {
9501 	prepare_assert_error(&ga);
9502 	ga_concat(&ga, (char_u *)"command did not fail: ");
9503 	ga_concat(&ga, cmd);
9504 	assert_error(&ga);
9505 	ga_clear(&ga);
9506     }
9507     else if (argvars[1].v_type != VAR_UNKNOWN)
9508     {
9509 	char_u	buf[NUMBUFLEN];
9510 	char	*error = (char *)get_tv_string_buf_chk(&argvars[1], buf);
9511 
9512 	if (error == NULL
9513 		  || strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL)
9514 	{
9515 	    prepare_assert_error(&ga);
9516 	    fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
9517 					    &vimvars[VV_ERRMSG].vv_tv, FALSE);
9518 	    assert_error(&ga);
9519 	    ga_clear(&ga);
9520 	}
9521     }
9522 
9523     called_emsg = FALSE;
9524     suppress_errthrow = FALSE;
9525     emsg_silent = FALSE;
9526     emsg_on_display = FALSE;
9527     set_vim_var_string(VV_ERRMSG, NULL, 0);
9528 }
9529 
9530 /*
9531  * Common for assert_true() and assert_false().
9532  */
9533     static void
9534 assert_bool(typval_T *argvars, int isTrue)
9535 {
9536     int		error = FALSE;
9537     garray_T	ga;
9538 
9539     if (argvars[0].v_type == VAR_SPECIAL
9540 	    && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE))
9541 	return;
9542     if (argvars[0].v_type != VAR_NUMBER
9543 	    || (get_tv_number_chk(&argvars[0], &error) == 0) == isTrue
9544 	    || error)
9545     {
9546 	prepare_assert_error(&ga);
9547 	fill_assert_error(&ga, &argvars[1],
9548 		(char_u *)(isTrue ? "True" : "False"),
9549 		NULL, &argvars[0], FALSE);
9550 	assert_error(&ga);
9551 	ga_clear(&ga);
9552     }
9553 }
9554 
9555 /*
9556  * "assert_false(actual[, msg])" function
9557  */
9558     static void
9559 f_assert_false(typval_T *argvars, typval_T *rettv UNUSED)
9560 {
9561     assert_bool(argvars, FALSE);
9562 }
9563 
9564 /*
9565  * "assert_match(pattern, actual[, msg])" function
9566  */
9567     static void
9568 f_assert_match(typval_T *argvars, typval_T *rettv UNUSED)
9569 {
9570     garray_T	ga;
9571     char_u	buf1[NUMBUFLEN];
9572     char_u	buf2[NUMBUFLEN];
9573     char_u	*pat = get_tv_string_buf_chk(&argvars[0], buf1);
9574     char_u	*text = get_tv_string_buf_chk(&argvars[1], buf2);
9575 
9576     if (!pattern_match(pat, text, FALSE))
9577     {
9578 	prepare_assert_error(&ga);
9579 	fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
9580 									TRUE);
9581 	assert_error(&ga);
9582 	ga_clear(&ga);
9583     }
9584 }
9585 
9586 /*
9587  * "assert_true(actual[, msg])" function
9588  */
9589     static void
9590 f_assert_true(typval_T *argvars, typval_T *rettv UNUSED)
9591 {
9592     assert_bool(argvars, TRUE);
9593 }
9594 
9595 #ifdef FEAT_FLOAT
9596 /*
9597  * "asin()" function
9598  */
9599     static void
9600 f_asin(typval_T *argvars, typval_T *rettv)
9601 {
9602     float_T	f = 0.0;
9603 
9604     rettv->v_type = VAR_FLOAT;
9605     if (get_float_arg(argvars, &f) == OK)
9606 	rettv->vval.v_float = asin(f);
9607     else
9608 	rettv->vval.v_float = 0.0;
9609 }
9610 
9611 /*
9612  * "atan()" function
9613  */
9614     static void
9615 f_atan(typval_T *argvars, typval_T *rettv)
9616 {
9617     float_T	f = 0.0;
9618 
9619     rettv->v_type = VAR_FLOAT;
9620     if (get_float_arg(argvars, &f) == OK)
9621 	rettv->vval.v_float = atan(f);
9622     else
9623 	rettv->vval.v_float = 0.0;
9624 }
9625 
9626 /*
9627  * "atan2()" function
9628  */
9629     static void
9630 f_atan2(typval_T *argvars, typval_T *rettv)
9631 {
9632     float_T	fx = 0.0, fy = 0.0;
9633 
9634     rettv->v_type = VAR_FLOAT;
9635     if (get_float_arg(argvars, &fx) == OK
9636 				     && get_float_arg(&argvars[1], &fy) == OK)
9637 	rettv->vval.v_float = atan2(fx, fy);
9638     else
9639 	rettv->vval.v_float = 0.0;
9640 }
9641 #endif
9642 
9643 /*
9644  * "browse(save, title, initdir, default)" function
9645  */
9646     static void
9647 f_browse(typval_T *argvars UNUSED, typval_T *rettv)
9648 {
9649 #ifdef FEAT_BROWSE
9650     int		save;
9651     char_u	*title;
9652     char_u	*initdir;
9653     char_u	*defname;
9654     char_u	buf[NUMBUFLEN];
9655     char_u	buf2[NUMBUFLEN];
9656     int		error = FALSE;
9657 
9658     save = get_tv_number_chk(&argvars[0], &error);
9659     title = get_tv_string_chk(&argvars[1]);
9660     initdir = get_tv_string_buf_chk(&argvars[2], buf);
9661     defname = get_tv_string_buf_chk(&argvars[3], buf2);
9662 
9663     if (error || title == NULL || initdir == NULL || defname == NULL)
9664 	rettv->vval.v_string = NULL;
9665     else
9666 	rettv->vval.v_string =
9667 		 do_browse(save ? BROWSE_SAVE : 0,
9668 				 title, defname, NULL, initdir, NULL, curbuf);
9669 #else
9670     rettv->vval.v_string = NULL;
9671 #endif
9672     rettv->v_type = VAR_STRING;
9673 }
9674 
9675 /*
9676  * "browsedir(title, initdir)" function
9677  */
9678     static void
9679 f_browsedir(typval_T *argvars UNUSED, typval_T *rettv)
9680 {
9681 #ifdef FEAT_BROWSE
9682     char_u	*title;
9683     char_u	*initdir;
9684     char_u	buf[NUMBUFLEN];
9685 
9686     title = get_tv_string_chk(&argvars[0]);
9687     initdir = get_tv_string_buf_chk(&argvars[1], buf);
9688 
9689     if (title == NULL || initdir == NULL)
9690 	rettv->vval.v_string = NULL;
9691     else
9692 	rettv->vval.v_string = do_browse(BROWSE_DIR,
9693 				    title, NULL, NULL, initdir, NULL, curbuf);
9694 #else
9695     rettv->vval.v_string = NULL;
9696 #endif
9697     rettv->v_type = VAR_STRING;
9698 }
9699 
9700 static buf_T *find_buffer(typval_T *avar);
9701 
9702 /*
9703  * Find a buffer by number or exact name.
9704  */
9705     static buf_T *
9706 find_buffer(typval_T *avar)
9707 {
9708     buf_T	*buf = NULL;
9709 
9710     if (avar->v_type == VAR_NUMBER)
9711 	buf = buflist_findnr((int)avar->vval.v_number);
9712     else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL)
9713     {
9714 	buf = buflist_findname_exp(avar->vval.v_string);
9715 	if (buf == NULL)
9716 	{
9717 	    /* No full path name match, try a match with a URL or a "nofile"
9718 	     * buffer, these don't use the full path. */
9719 	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
9720 		if (buf->b_fname != NULL
9721 			&& (path_with_url(buf->b_fname)
9722 #ifdef FEAT_QUICKFIX
9723 			    || bt_nofile(buf)
9724 #endif
9725 			   )
9726 			&& STRCMP(buf->b_fname, avar->vval.v_string) == 0)
9727 		    break;
9728 	}
9729     }
9730     return buf;
9731 }
9732 
9733 /*
9734  * "bufexists(expr)" function
9735  */
9736     static void
9737 f_bufexists(typval_T *argvars, typval_T *rettv)
9738 {
9739     rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL);
9740 }
9741 
9742 /*
9743  * "buflisted(expr)" function
9744  */
9745     static void
9746 f_buflisted(typval_T *argvars, typval_T *rettv)
9747 {
9748     buf_T	*buf;
9749 
9750     buf = find_buffer(&argvars[0]);
9751     rettv->vval.v_number = (buf != NULL && buf->b_p_bl);
9752 }
9753 
9754 /*
9755  * "bufloaded(expr)" function
9756  */
9757     static void
9758 f_bufloaded(typval_T *argvars, typval_T *rettv)
9759 {
9760     buf_T	*buf;
9761 
9762     buf = find_buffer(&argvars[0]);
9763     rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
9764 }
9765 
9766     buf_T *
9767 buflist_find_by_name(char_u *name, int curtab_only)
9768 {
9769     int		save_magic;
9770     char_u	*save_cpo;
9771     buf_T	*buf;
9772 
9773     /* Ignore 'magic' and 'cpoptions' here to make scripts portable */
9774     save_magic = p_magic;
9775     p_magic = TRUE;
9776     save_cpo = p_cpo;
9777     p_cpo = (char_u *)"";
9778 
9779     buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
9780 						    TRUE, FALSE, curtab_only));
9781 
9782     p_magic = save_magic;
9783     p_cpo = save_cpo;
9784     return buf;
9785 }
9786 
9787 /*
9788  * Get buffer by number or pattern.
9789  */
9790     static buf_T *
9791 get_buf_tv(typval_T *tv, int curtab_only)
9792 {
9793     char_u	*name = tv->vval.v_string;
9794     buf_T	*buf;
9795 
9796     if (tv->v_type == VAR_NUMBER)
9797 	return buflist_findnr((int)tv->vval.v_number);
9798     if (tv->v_type != VAR_STRING)
9799 	return NULL;
9800     if (name == NULL || *name == NUL)
9801 	return curbuf;
9802     if (name[0] == '$' && name[1] == NUL)
9803 	return lastbuf;
9804 
9805     buf = buflist_find_by_name(name, curtab_only);
9806 
9807     /* If not found, try expanding the name, like done for bufexists(). */
9808     if (buf == NULL)
9809 	buf = find_buffer(tv);
9810 
9811     return buf;
9812 }
9813 
9814 /*
9815  * "bufname(expr)" function
9816  */
9817     static void
9818 f_bufname(typval_T *argvars, typval_T *rettv)
9819 {
9820     buf_T	*buf;
9821 
9822     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
9823     ++emsg_off;
9824     buf = get_buf_tv(&argvars[0], FALSE);
9825     rettv->v_type = VAR_STRING;
9826     if (buf != NULL && buf->b_fname != NULL)
9827 	rettv->vval.v_string = vim_strsave(buf->b_fname);
9828     else
9829 	rettv->vval.v_string = NULL;
9830     --emsg_off;
9831 }
9832 
9833 /*
9834  * "bufnr(expr)" function
9835  */
9836     static void
9837 f_bufnr(typval_T *argvars, typval_T *rettv)
9838 {
9839     buf_T	*buf;
9840     int		error = FALSE;
9841     char_u	*name;
9842 
9843     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
9844     ++emsg_off;
9845     buf = get_buf_tv(&argvars[0], FALSE);
9846     --emsg_off;
9847 
9848     /* If the buffer isn't found and the second argument is not zero create a
9849      * new buffer. */
9850     if (buf == NULL
9851 	    && argvars[1].v_type != VAR_UNKNOWN
9852 	    && get_tv_number_chk(&argvars[1], &error) != 0
9853 	    && !error
9854 	    && (name = get_tv_string_chk(&argvars[0])) != NULL
9855 	    && !error)
9856 	buf = buflist_new(name, NULL, (linenr_T)1, 0);
9857 
9858     if (buf != NULL)
9859 	rettv->vval.v_number = buf->b_fnum;
9860     else
9861 	rettv->vval.v_number = -1;
9862 }
9863 
9864 /*
9865  * "bufwinnr(nr)" function
9866  */
9867     static void
9868 f_bufwinnr(typval_T *argvars, typval_T *rettv)
9869 {
9870 #ifdef FEAT_WINDOWS
9871     win_T	*wp;
9872     int		winnr = 0;
9873 #endif
9874     buf_T	*buf;
9875 
9876     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
9877     ++emsg_off;
9878     buf = get_buf_tv(&argvars[0], TRUE);
9879 #ifdef FEAT_WINDOWS
9880     for (wp = firstwin; wp; wp = wp->w_next)
9881     {
9882 	++winnr;
9883 	if (wp->w_buffer == buf)
9884 	    break;
9885     }
9886     rettv->vval.v_number = (wp != NULL ? winnr : -1);
9887 #else
9888     rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1);
9889 #endif
9890     --emsg_off;
9891 }
9892 
9893 /*
9894  * "byte2line(byte)" function
9895  */
9896     static void
9897 f_byte2line(typval_T *argvars UNUSED, typval_T *rettv)
9898 {
9899 #ifndef FEAT_BYTEOFF
9900     rettv->vval.v_number = -1;
9901 #else
9902     long	boff = 0;
9903 
9904     boff = get_tv_number(&argvars[0]) - 1;  /* boff gets -1 on type error */
9905     if (boff < 0)
9906 	rettv->vval.v_number = -1;
9907     else
9908 	rettv->vval.v_number = ml_find_line_or_offset(curbuf,
9909 							  (linenr_T)0, &boff);
9910 #endif
9911 }
9912 
9913     static void
9914 byteidx(typval_T *argvars, typval_T *rettv, int comp UNUSED)
9915 {
9916 #ifdef FEAT_MBYTE
9917     char_u	*t;
9918 #endif
9919     char_u	*str;
9920     long	idx;
9921 
9922     str = get_tv_string_chk(&argvars[0]);
9923     idx = get_tv_number_chk(&argvars[1], NULL);
9924     rettv->vval.v_number = -1;
9925     if (str == NULL || idx < 0)
9926 	return;
9927 
9928 #ifdef FEAT_MBYTE
9929     t = str;
9930     for ( ; idx > 0; idx--)
9931     {
9932 	if (*t == NUL)		/* EOL reached */
9933 	    return;
9934 	if (enc_utf8 && comp)
9935 	    t += utf_ptr2len(t);
9936 	else
9937 	    t += (*mb_ptr2len)(t);
9938     }
9939     rettv->vval.v_number = (varnumber_T)(t - str);
9940 #else
9941     if ((size_t)idx <= STRLEN(str))
9942 	rettv->vval.v_number = idx;
9943 #endif
9944 }
9945 
9946 /*
9947  * "byteidx()" function
9948  */
9949     static void
9950 f_byteidx(typval_T *argvars, typval_T *rettv)
9951 {
9952     byteidx(argvars, rettv, FALSE);
9953 }
9954 
9955 /*
9956  * "byteidxcomp()" function
9957  */
9958     static void
9959 f_byteidxcomp(typval_T *argvars, typval_T *rettv)
9960 {
9961     byteidx(argvars, rettv, TRUE);
9962 }
9963 
9964     int
9965 func_call(
9966     char_u	*name,
9967     typval_T	*args,
9968     partial_T	*partial,
9969     dict_T	*selfdict,
9970     typval_T	*rettv)
9971 {
9972     listitem_T	*item;
9973     typval_T	argv[MAX_FUNC_ARGS + 1];
9974     int		argc = 0;
9975     int		dummy;
9976     int		r = 0;
9977 
9978     for (item = args->vval.v_list->lv_first; item != NULL;
9979 							 item = item->li_next)
9980     {
9981 	if (argc == MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc))
9982 	{
9983 	    EMSG(_("E699: Too many arguments"));
9984 	    break;
9985 	}
9986 	/* Make a copy of each argument.  This is needed to be able to set
9987 	 * v_lock to VAR_FIXED in the copy without changing the original list.
9988 	 */
9989 	copy_tv(&item->li_tv, &argv[argc++]);
9990     }
9991 
9992     if (item == NULL)
9993 	r = call_func(name, (int)STRLEN(name), rettv, argc, argv,
9994 				 curwin->w_cursor.lnum, curwin->w_cursor.lnum,
9995 					     &dummy, TRUE, partial, selfdict);
9996 
9997     /* Free the arguments. */
9998     while (argc > 0)
9999 	clear_tv(&argv[--argc]);
10000 
10001     return r;
10002 }
10003 
10004 /*
10005  * "call(func, arglist [, dict])" function
10006  */
10007     static void
10008 f_call(typval_T *argvars, typval_T *rettv)
10009 {
10010     char_u	*func;
10011     partial_T   *partial = NULL;
10012     dict_T	*selfdict = NULL;
10013 
10014     if (argvars[1].v_type != VAR_LIST)
10015     {
10016 	EMSG(_(e_listreq));
10017 	return;
10018     }
10019     if (argvars[1].vval.v_list == NULL)
10020 	return;
10021 
10022     if (argvars[0].v_type == VAR_FUNC)
10023 	func = argvars[0].vval.v_string;
10024     else if (argvars[0].v_type == VAR_PARTIAL)
10025     {
10026 	partial = argvars[0].vval.v_partial;
10027 	func = partial->pt_name;
10028     }
10029     else
10030 	func = get_tv_string(&argvars[0]);
10031     if (*func == NUL)
10032 	return;		/* type error or empty name */
10033 
10034     if (argvars[2].v_type != VAR_UNKNOWN)
10035     {
10036 	if (argvars[2].v_type != VAR_DICT)
10037 	{
10038 	    EMSG(_(e_dictreq));
10039 	    return;
10040 	}
10041 	selfdict = argvars[2].vval.v_dict;
10042     }
10043 
10044     (void)func_call(func, &argvars[1], partial, selfdict, rettv);
10045 }
10046 
10047 #ifdef FEAT_FLOAT
10048 /*
10049  * "ceil({float})" function
10050  */
10051     static void
10052 f_ceil(typval_T *argvars, typval_T *rettv)
10053 {
10054     float_T	f = 0.0;
10055 
10056     rettv->v_type = VAR_FLOAT;
10057     if (get_float_arg(argvars, &f) == OK)
10058 	rettv->vval.v_float = ceil(f);
10059     else
10060 	rettv->vval.v_float = 0.0;
10061 }
10062 #endif
10063 
10064 #ifdef FEAT_JOB_CHANNEL
10065 /*
10066  * "ch_close()" function
10067  */
10068     static void
10069 f_ch_close(typval_T *argvars, typval_T *rettv UNUSED)
10070 {
10071     channel_T *channel = get_channel_arg(&argvars[0], TRUE);
10072 
10073     if (channel != NULL)
10074     {
10075 	channel_close(channel, FALSE);
10076 	channel_clear(channel);
10077     }
10078 }
10079 
10080 /*
10081  * "ch_getbufnr()" function
10082  */
10083     static void
10084 f_ch_getbufnr(typval_T *argvars, typval_T *rettv)
10085 {
10086     channel_T *channel = get_channel_arg(&argvars[0], TRUE);
10087 
10088     rettv->vval.v_number = -1;
10089     if (channel != NULL)
10090     {
10091 	char_u	*what = get_tv_string(&argvars[1]);
10092 	int	part;
10093 
10094 	if (STRCMP(what, "err") == 0)
10095 	    part = PART_ERR;
10096 	else if (STRCMP(what, "out") == 0)
10097 	    part = PART_OUT;
10098 	else if (STRCMP(what, "in") == 0)
10099 	    part = PART_IN;
10100 	else
10101 	    part = PART_SOCK;
10102 	if (channel->ch_part[part].ch_buffer != NULL)
10103 	    rettv->vval.v_number = channel->ch_part[part].ch_buffer->b_fnum;
10104     }
10105 }
10106 
10107 /*
10108  * "ch_getjob()" function
10109  */
10110     static void
10111 f_ch_getjob(typval_T *argvars, typval_T *rettv)
10112 {
10113     channel_T *channel = get_channel_arg(&argvars[0], TRUE);
10114 
10115     if (channel != NULL)
10116     {
10117 	rettv->v_type = VAR_JOB;
10118 	rettv->vval.v_job = channel->ch_job;
10119 	if (channel->ch_job != NULL)
10120 	    ++channel->ch_job->jv_refcount;
10121     }
10122 }
10123 
10124 /*
10125  * "ch_info()" function
10126  */
10127     static void
10128 f_ch_info(typval_T *argvars, typval_T *rettv UNUSED)
10129 {
10130     channel_T *channel = get_channel_arg(&argvars[0], TRUE);
10131 
10132     if (channel != NULL && rettv_dict_alloc(rettv) != FAIL)
10133 	channel_info(channel, rettv->vval.v_dict);
10134 }
10135 
10136 /*
10137  * "ch_log()" function
10138  */
10139     static void
10140 f_ch_log(typval_T *argvars, typval_T *rettv UNUSED)
10141 {
10142     char_u	*msg = get_tv_string(&argvars[0]);
10143     channel_T	*channel = NULL;
10144 
10145     if (argvars[1].v_type != VAR_UNKNOWN)
10146 	channel = get_channel_arg(&argvars[1], TRUE);
10147 
10148     ch_log(channel, (char *)msg);
10149 }
10150 
10151 /*
10152  * "ch_logfile()" function
10153  */
10154     static void
10155 f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED)
10156 {
10157     char_u *fname;
10158     char_u *opt = (char_u *)"";
10159     char_u buf[NUMBUFLEN];
10160 
10161     fname = get_tv_string(&argvars[0]);
10162     if (argvars[1].v_type == VAR_STRING)
10163 	opt = get_tv_string_buf(&argvars[1], buf);
10164     ch_logfile(fname, opt);
10165 }
10166 
10167 /*
10168  * "ch_open()" function
10169  */
10170     static void
10171 f_ch_open(typval_T *argvars, typval_T *rettv)
10172 {
10173     rettv->v_type = VAR_CHANNEL;
10174     rettv->vval.v_channel = channel_open_func(argvars);
10175 }
10176 
10177 /*
10178  * "ch_read()" function
10179  */
10180     static void
10181 f_ch_read(typval_T *argvars, typval_T *rettv)
10182 {
10183     common_channel_read(argvars, rettv, FALSE);
10184 }
10185 
10186 /*
10187  * "ch_readraw()" function
10188  */
10189     static void
10190 f_ch_readraw(typval_T *argvars, typval_T *rettv)
10191 {
10192     common_channel_read(argvars, rettv, TRUE);
10193 }
10194 
10195 /*
10196  * "ch_evalexpr()" function
10197  */
10198     static void
10199 f_ch_evalexpr(typval_T *argvars, typval_T *rettv)
10200 {
10201     ch_expr_common(argvars, rettv, TRUE);
10202 }
10203 
10204 /*
10205  * "ch_sendexpr()" function
10206  */
10207     static void
10208 f_ch_sendexpr(typval_T *argvars, typval_T *rettv)
10209 {
10210     ch_expr_common(argvars, rettv, FALSE);
10211 }
10212 
10213 /*
10214  * "ch_evalraw()" function
10215  */
10216     static void
10217 f_ch_evalraw(typval_T *argvars, typval_T *rettv)
10218 {
10219     ch_raw_common(argvars, rettv, TRUE);
10220 }
10221 
10222 /*
10223  * "ch_sendraw()" function
10224  */
10225     static void
10226 f_ch_sendraw(typval_T *argvars, typval_T *rettv)
10227 {
10228     ch_raw_common(argvars, rettv, FALSE);
10229 }
10230 
10231 /*
10232  * "ch_setoptions()" function
10233  */
10234     static void
10235 f_ch_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
10236 {
10237     channel_T	*channel;
10238     jobopt_T	opt;
10239 
10240     channel = get_channel_arg(&argvars[0], TRUE);
10241     if (channel == NULL)
10242 	return;
10243     clear_job_options(&opt);
10244     if (get_job_options(&argvars[1], &opt,
10245 		JO_CB_ALL + JO_TIMEOUT_ALL + JO_MODE_ALL) == FAIL)
10246 	return;
10247     channel_set_options(channel, &opt);
10248 }
10249 
10250 /*
10251  * "ch_status()" function
10252  */
10253     static void
10254 f_ch_status(typval_T *argvars, typval_T *rettv)
10255 {
10256     channel_T	*channel;
10257 
10258     /* return an empty string by default */
10259     rettv->v_type = VAR_STRING;
10260     rettv->vval.v_string = NULL;
10261 
10262     channel = get_channel_arg(&argvars[0], FALSE);
10263     rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel));
10264 }
10265 #endif
10266 
10267 /*
10268  * "changenr()" function
10269  */
10270     static void
10271 f_changenr(typval_T *argvars UNUSED, typval_T *rettv)
10272 {
10273     rettv->vval.v_number = curbuf->b_u_seq_cur;
10274 }
10275 
10276 /*
10277  * "char2nr(string)" function
10278  */
10279     static void
10280 f_char2nr(typval_T *argvars, typval_T *rettv)
10281 {
10282 #ifdef FEAT_MBYTE
10283     if (has_mbyte)
10284     {
10285 	int	utf8 = 0;
10286 
10287 	if (argvars[1].v_type != VAR_UNKNOWN)
10288 	    utf8 = get_tv_number_chk(&argvars[1], NULL);
10289 
10290 	if (utf8)
10291 	    rettv->vval.v_number = (*utf_ptr2char)(get_tv_string(&argvars[0]));
10292 	else
10293 	    rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0]));
10294     }
10295     else
10296 #endif
10297     rettv->vval.v_number = get_tv_string(&argvars[0])[0];
10298 }
10299 
10300 /*
10301  * "cindent(lnum)" function
10302  */
10303     static void
10304 f_cindent(typval_T *argvars UNUSED, typval_T *rettv)
10305 {
10306 #ifdef FEAT_CINDENT
10307     pos_T	pos;
10308     linenr_T	lnum;
10309 
10310     pos = curwin->w_cursor;
10311     lnum = get_tv_lnum(argvars);
10312     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
10313     {
10314 	curwin->w_cursor.lnum = lnum;
10315 	rettv->vval.v_number = get_c_indent();
10316 	curwin->w_cursor = pos;
10317     }
10318     else
10319 #endif
10320 	rettv->vval.v_number = -1;
10321 }
10322 
10323 /*
10324  * "clearmatches()" function
10325  */
10326     static void
10327 f_clearmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10328 {
10329 #ifdef FEAT_SEARCH_EXTRA
10330     clear_matches(curwin);
10331 #endif
10332 }
10333 
10334 /*
10335  * "col(string)" function
10336  */
10337     static void
10338 f_col(typval_T *argvars, typval_T *rettv)
10339 {
10340     colnr_T	col = 0;
10341     pos_T	*fp;
10342     int		fnum = curbuf->b_fnum;
10343 
10344     fp = var2fpos(&argvars[0], FALSE, &fnum);
10345     if (fp != NULL && fnum == curbuf->b_fnum)
10346     {
10347 	if (fp->col == MAXCOL)
10348 	{
10349 	    /* '> can be MAXCOL, get the length of the line then */
10350 	    if (fp->lnum <= curbuf->b_ml.ml_line_count)
10351 		col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1;
10352 	    else
10353 		col = MAXCOL;
10354 	}
10355 	else
10356 	{
10357 	    col = fp->col + 1;
10358 #ifdef FEAT_VIRTUALEDIT
10359 	    /* col(".") when the cursor is on the NUL at the end of the line
10360 	     * because of "coladd" can be seen as an extra column. */
10361 	    if (virtual_active() && fp == &curwin->w_cursor)
10362 	    {
10363 		char_u	*p = ml_get_cursor();
10364 
10365 		if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p,
10366 				 curwin->w_virtcol - curwin->w_cursor.coladd))
10367 		{
10368 # ifdef FEAT_MBYTE
10369 		    int		l;
10370 
10371 		    if (*p != NUL && p[(l = (*mb_ptr2len)(p))] == NUL)
10372 			col += l;
10373 # else
10374 		    if (*p != NUL && p[1] == NUL)
10375 			++col;
10376 # endif
10377 		}
10378 	    }
10379 #endif
10380 	}
10381     }
10382     rettv->vval.v_number = col;
10383 }
10384 
10385 #if defined(FEAT_INS_EXPAND)
10386 /*
10387  * "complete()" function
10388  */
10389     static void
10390 f_complete(typval_T *argvars, typval_T *rettv UNUSED)
10391 {
10392     int	    startcol;
10393 
10394     if ((State & INSERT) == 0)
10395     {
10396 	EMSG(_("E785: complete() can only be used in Insert mode"));
10397 	return;
10398     }
10399 
10400     /* Check for undo allowed here, because if something was already inserted
10401      * the line was already saved for undo and this check isn't done. */
10402     if (!undo_allowed())
10403 	return;
10404 
10405     if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL)
10406     {
10407 	EMSG(_(e_invarg));
10408 	return;
10409     }
10410 
10411     startcol = get_tv_number_chk(&argvars[0], NULL);
10412     if (startcol <= 0)
10413 	return;
10414 
10415     set_completion(startcol - 1, argvars[1].vval.v_list);
10416 }
10417 
10418 /*
10419  * "complete_add()" function
10420  */
10421     static void
10422 f_complete_add(typval_T *argvars, typval_T *rettv)
10423 {
10424     rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0);
10425 }
10426 
10427 /*
10428  * "complete_check()" function
10429  */
10430     static void
10431 f_complete_check(typval_T *argvars UNUSED, typval_T *rettv)
10432 {
10433     int		saved = RedrawingDisabled;
10434 
10435     RedrawingDisabled = 0;
10436     ins_compl_check_keys(0);
10437     rettv->vval.v_number = compl_interrupted;
10438     RedrawingDisabled = saved;
10439 }
10440 #endif
10441 
10442 /*
10443  * "confirm(message, buttons[, default [, type]])" function
10444  */
10445     static void
10446 f_confirm(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10447 {
10448 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
10449     char_u	*message;
10450     char_u	*buttons = NULL;
10451     char_u	buf[NUMBUFLEN];
10452     char_u	buf2[NUMBUFLEN];
10453     int		def = 1;
10454     int		type = VIM_GENERIC;
10455     char_u	*typestr;
10456     int		error = FALSE;
10457 
10458     message = get_tv_string_chk(&argvars[0]);
10459     if (message == NULL)
10460 	error = TRUE;
10461     if (argvars[1].v_type != VAR_UNKNOWN)
10462     {
10463 	buttons = get_tv_string_buf_chk(&argvars[1], buf);
10464 	if (buttons == NULL)
10465 	    error = TRUE;
10466 	if (argvars[2].v_type != VAR_UNKNOWN)
10467 	{
10468 	    def = get_tv_number_chk(&argvars[2], &error);
10469 	    if (argvars[3].v_type != VAR_UNKNOWN)
10470 	    {
10471 		typestr = get_tv_string_buf_chk(&argvars[3], buf2);
10472 		if (typestr == NULL)
10473 		    error = TRUE;
10474 		else
10475 		{
10476 		    switch (TOUPPER_ASC(*typestr))
10477 		    {
10478 			case 'E': type = VIM_ERROR; break;
10479 			case 'Q': type = VIM_QUESTION; break;
10480 			case 'I': type = VIM_INFO; break;
10481 			case 'W': type = VIM_WARNING; break;
10482 			case 'G': type = VIM_GENERIC; break;
10483 		    }
10484 		}
10485 	    }
10486 	}
10487     }
10488 
10489     if (buttons == NULL || *buttons == NUL)
10490 	buttons = (char_u *)_("&Ok");
10491 
10492     if (!error)
10493 	rettv->vval.v_number = do_dialog(type, NULL, message, buttons,
10494 							    def, NULL, FALSE);
10495 #endif
10496 }
10497 
10498 /*
10499  * "copy()" function
10500  */
10501     static void
10502 f_copy(typval_T *argvars, typval_T *rettv)
10503 {
10504     item_copy(&argvars[0], rettv, FALSE, 0);
10505 }
10506 
10507 #ifdef FEAT_FLOAT
10508 /*
10509  * "cos()" function
10510  */
10511     static void
10512 f_cos(typval_T *argvars, typval_T *rettv)
10513 {
10514     float_T	f = 0.0;
10515 
10516     rettv->v_type = VAR_FLOAT;
10517     if (get_float_arg(argvars, &f) == OK)
10518 	rettv->vval.v_float = cos(f);
10519     else
10520 	rettv->vval.v_float = 0.0;
10521 }
10522 
10523 /*
10524  * "cosh()" function
10525  */
10526     static void
10527 f_cosh(typval_T *argvars, typval_T *rettv)
10528 {
10529     float_T	f = 0.0;
10530 
10531     rettv->v_type = VAR_FLOAT;
10532     if (get_float_arg(argvars, &f) == OK)
10533 	rettv->vval.v_float = cosh(f);
10534     else
10535 	rettv->vval.v_float = 0.0;
10536 }
10537 #endif
10538 
10539 /*
10540  * "count()" function
10541  */
10542     static void
10543 f_count(typval_T *argvars, typval_T *rettv)
10544 {
10545     long	n = 0;
10546     int		ic = FALSE;
10547 
10548     if (argvars[0].v_type == VAR_LIST)
10549     {
10550 	listitem_T	*li;
10551 	list_T		*l;
10552 	long		idx;
10553 
10554 	if ((l = argvars[0].vval.v_list) != NULL)
10555 	{
10556 	    li = l->lv_first;
10557 	    if (argvars[2].v_type != VAR_UNKNOWN)
10558 	    {
10559 		int error = FALSE;
10560 
10561 		ic = get_tv_number_chk(&argvars[2], &error);
10562 		if (argvars[3].v_type != VAR_UNKNOWN)
10563 		{
10564 		    idx = get_tv_number_chk(&argvars[3], &error);
10565 		    if (!error)
10566 		    {
10567 			li = list_find(l, idx);
10568 			if (li == NULL)
10569 			    EMSGN(_(e_listidx), idx);
10570 		    }
10571 		}
10572 		if (error)
10573 		    li = NULL;
10574 	    }
10575 
10576 	    for ( ; li != NULL; li = li->li_next)
10577 		if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE))
10578 		    ++n;
10579 	}
10580     }
10581     else if (argvars[0].v_type == VAR_DICT)
10582     {
10583 	int		todo;
10584 	dict_T		*d;
10585 	hashitem_T	*hi;
10586 
10587 	if ((d = argvars[0].vval.v_dict) != NULL)
10588 	{
10589 	    int error = FALSE;
10590 
10591 	    if (argvars[2].v_type != VAR_UNKNOWN)
10592 	    {
10593 		ic = get_tv_number_chk(&argvars[2], &error);
10594 		if (argvars[3].v_type != VAR_UNKNOWN)
10595 		    EMSG(_(e_invarg));
10596 	    }
10597 
10598 	    todo = error ? 0 : (int)d->dv_hashtab.ht_used;
10599 	    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
10600 	    {
10601 		if (!HASHITEM_EMPTY(hi))
10602 		{
10603 		    --todo;
10604 		    if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE))
10605 			++n;
10606 		}
10607 	    }
10608 	}
10609     }
10610     else
10611 	EMSG2(_(e_listdictarg), "count()");
10612     rettv->vval.v_number = n;
10613 }
10614 
10615 /*
10616  * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
10617  *
10618  * Checks the existence of a cscope connection.
10619  */
10620     static void
10621 f_cscope_connection(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10622 {
10623 #ifdef FEAT_CSCOPE
10624     int		num = 0;
10625     char_u	*dbpath = NULL;
10626     char_u	*prepend = NULL;
10627     char_u	buf[NUMBUFLEN];
10628 
10629     if (argvars[0].v_type != VAR_UNKNOWN
10630 	    && argvars[1].v_type != VAR_UNKNOWN)
10631     {
10632 	num = (int)get_tv_number(&argvars[0]);
10633 	dbpath = get_tv_string(&argvars[1]);
10634 	if (argvars[2].v_type != VAR_UNKNOWN)
10635 	    prepend = get_tv_string_buf(&argvars[2], buf);
10636     }
10637 
10638     rettv->vval.v_number = cs_connection(num, dbpath, prepend);
10639 #endif
10640 }
10641 
10642 /*
10643  * "cursor(lnum, col)" function, or
10644  * "cursor(list)"
10645  *
10646  * Moves the cursor to the specified line and column.
10647  * Returns 0 when the position could be set, -1 otherwise.
10648  */
10649     static void
10650 f_cursor(typval_T *argvars, typval_T *rettv)
10651 {
10652     long	line, col;
10653 #ifdef FEAT_VIRTUALEDIT
10654     long	coladd = 0;
10655 #endif
10656     int		set_curswant = TRUE;
10657 
10658     rettv->vval.v_number = -1;
10659     if (argvars[1].v_type == VAR_UNKNOWN)
10660     {
10661 	pos_T	    pos;
10662 	colnr_T	    curswant = -1;
10663 
10664 	if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL)
10665 	{
10666 	    EMSG(_(e_invarg));
10667 	    return;
10668 	}
10669 	line = pos.lnum;
10670 	col = pos.col;
10671 #ifdef FEAT_VIRTUALEDIT
10672 	coladd = pos.coladd;
10673 #endif
10674 	if (curswant >= 0)
10675 	{
10676 	    curwin->w_curswant = curswant - 1;
10677 	    set_curswant = FALSE;
10678 	}
10679     }
10680     else
10681     {
10682 	line = get_tv_lnum(argvars);
10683 	col = get_tv_number_chk(&argvars[1], NULL);
10684 #ifdef FEAT_VIRTUALEDIT
10685 	if (argvars[2].v_type != VAR_UNKNOWN)
10686 	    coladd = get_tv_number_chk(&argvars[2], NULL);
10687 #endif
10688     }
10689     if (line < 0 || col < 0
10690 #ifdef FEAT_VIRTUALEDIT
10691 			    || coladd < 0
10692 #endif
10693 	    )
10694 	return;		/* type error; errmsg already given */
10695     if (line > 0)
10696 	curwin->w_cursor.lnum = line;
10697     if (col > 0)
10698 	curwin->w_cursor.col = col - 1;
10699 #ifdef FEAT_VIRTUALEDIT
10700     curwin->w_cursor.coladd = coladd;
10701 #endif
10702 
10703     /* Make sure the cursor is in a valid position. */
10704     check_cursor();
10705 #ifdef FEAT_MBYTE
10706     /* Correct cursor for multi-byte character. */
10707     if (has_mbyte)
10708 	mb_adjust_cursor();
10709 #endif
10710 
10711     curwin->w_set_curswant = set_curswant;
10712     rettv->vval.v_number = 0;
10713 }
10714 
10715 /*
10716  * "deepcopy()" function
10717  */
10718     static void
10719 f_deepcopy(typval_T *argvars, typval_T *rettv)
10720 {
10721     int		noref = 0;
10722 
10723     if (argvars[1].v_type != VAR_UNKNOWN)
10724 	noref = get_tv_number_chk(&argvars[1], NULL);
10725     if (noref < 0 || noref > 1)
10726 	EMSG(_(e_invarg));
10727     else
10728     {
10729 	current_copyID += COPYID_INC;
10730 	item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0);
10731     }
10732 }
10733 
10734 /*
10735  * "delete()" function
10736  */
10737     static void
10738 f_delete(typval_T *argvars, typval_T *rettv)
10739 {
10740     char_u	nbuf[NUMBUFLEN];
10741     char_u	*name;
10742     char_u	*flags;
10743 
10744     rettv->vval.v_number = -1;
10745     if (check_restricted() || check_secure())
10746 	return;
10747 
10748     name = get_tv_string(&argvars[0]);
10749     if (name == NULL || *name == NUL)
10750     {
10751 	EMSG(_(e_invarg));
10752 	return;
10753     }
10754 
10755     if (argvars[1].v_type != VAR_UNKNOWN)
10756 	flags = get_tv_string_buf(&argvars[1], nbuf);
10757     else
10758 	flags = (char_u *)"";
10759 
10760     if (*flags == NUL)
10761 	/* delete a file */
10762 	rettv->vval.v_number = mch_remove(name) == 0 ? 0 : -1;
10763     else if (STRCMP(flags, "d") == 0)
10764 	/* delete an empty directory */
10765 	rettv->vval.v_number = mch_rmdir(name) == 0 ? 0 : -1;
10766     else if (STRCMP(flags, "rf") == 0)
10767 	/* delete a directory recursively */
10768 	rettv->vval.v_number = delete_recursive(name);
10769     else
10770 	EMSG2(_(e_invexpr2), flags);
10771 }
10772 
10773 /*
10774  * "did_filetype()" function
10775  */
10776     static void
10777 f_did_filetype(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10778 {
10779 #ifdef FEAT_AUTOCMD
10780     rettv->vval.v_number = did_filetype;
10781 #endif
10782 }
10783 
10784 /*
10785  * "diff_filler()" function
10786  */
10787     static void
10788 f_diff_filler(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10789 {
10790 #ifdef FEAT_DIFF
10791     rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars));
10792 #endif
10793 }
10794 
10795 /*
10796  * "diff_hlID()" function
10797  */
10798     static void
10799 f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
10800 {
10801 #ifdef FEAT_DIFF
10802     linenr_T		lnum = get_tv_lnum(argvars);
10803     static linenr_T	prev_lnum = 0;
10804     static int		changedtick = 0;
10805     static int		fnum = 0;
10806     static int		change_start = 0;
10807     static int		change_end = 0;
10808     static hlf_T	hlID = (hlf_T)0;
10809     int			filler_lines;
10810     int			col;
10811 
10812     if (lnum < 0)	/* ignore type error in {lnum} arg */
10813 	lnum = 0;
10814     if (lnum != prev_lnum
10815 	    || changedtick != curbuf->b_changedtick
10816 	    || fnum != curbuf->b_fnum)
10817     {
10818 	/* New line, buffer, change: need to get the values. */
10819 	filler_lines = diff_check(curwin, lnum);
10820 	if (filler_lines < 0)
10821 	{
10822 	    if (filler_lines == -1)
10823 	    {
10824 		change_start = MAXCOL;
10825 		change_end = -1;
10826 		if (diff_find_change(curwin, lnum, &change_start, &change_end))
10827 		    hlID = HLF_ADD;	/* added line */
10828 		else
10829 		    hlID = HLF_CHD;	/* changed line */
10830 	    }
10831 	    else
10832 		hlID = HLF_ADD;	/* added line */
10833 	}
10834 	else
10835 	    hlID = (hlf_T)0;
10836 	prev_lnum = lnum;
10837 	changedtick = curbuf->b_changedtick;
10838 	fnum = curbuf->b_fnum;
10839     }
10840 
10841     if (hlID == HLF_CHD || hlID == HLF_TXD)
10842     {
10843 	col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */
10844 	if (col >= change_start && col <= change_end)
10845 	    hlID = HLF_TXD;			/* changed text */
10846 	else
10847 	    hlID = HLF_CHD;			/* changed line */
10848     }
10849     rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID;
10850 #endif
10851 }
10852 
10853 /*
10854  * "disable_char_avail_for_testing({expr})" function
10855  */
10856     static void
10857 f_disable_char_avail_for_testing(typval_T *argvars, typval_T *rettv UNUSED)
10858 {
10859     disable_char_avail_for_testing = get_tv_number(&argvars[0]);
10860 }
10861 
10862 /*
10863  * "empty({expr})" function
10864  */
10865     static void
10866 f_empty(typval_T *argvars, typval_T *rettv)
10867 {
10868     int		n = FALSE;
10869 
10870     switch (argvars[0].v_type)
10871     {
10872 	case VAR_STRING:
10873 	case VAR_FUNC:
10874 	    n = argvars[0].vval.v_string == NULL
10875 					  || *argvars[0].vval.v_string == NUL;
10876 	    break;
10877 	case VAR_PARTIAL:
10878 	    n = FALSE;
10879 	    break;
10880 	case VAR_NUMBER:
10881 	    n = argvars[0].vval.v_number == 0;
10882 	    break;
10883 	case VAR_FLOAT:
10884 #ifdef FEAT_FLOAT
10885 	    n = argvars[0].vval.v_float == 0.0;
10886 	    break;
10887 #endif
10888 	case VAR_LIST:
10889 	    n = argvars[0].vval.v_list == NULL
10890 				  || argvars[0].vval.v_list->lv_first == NULL;
10891 	    break;
10892 	case VAR_DICT:
10893 	    n = argvars[0].vval.v_dict == NULL
10894 			|| argvars[0].vval.v_dict->dv_hashtab.ht_used == 0;
10895 	    break;
10896 	case VAR_SPECIAL:
10897 	    n = argvars[0].vval.v_number != VVAL_TRUE;
10898 	    break;
10899 
10900 	case VAR_JOB:
10901 #ifdef FEAT_JOB_CHANNEL
10902 	    n = argvars[0].vval.v_job == NULL
10903 			   || argvars[0].vval.v_job->jv_status != JOB_STARTED;
10904 	    break;
10905 #endif
10906 	case VAR_CHANNEL:
10907 #ifdef FEAT_JOB_CHANNEL
10908 	    n = argvars[0].vval.v_channel == NULL
10909 			       || !channel_is_open(argvars[0].vval.v_channel);
10910 	    break;
10911 #endif
10912 	case VAR_UNKNOWN:
10913 	    EMSG2(_(e_intern2), "f_empty(UNKNOWN)");
10914 	    n = TRUE;
10915 	    break;
10916     }
10917 
10918     rettv->vval.v_number = n;
10919 }
10920 
10921 /*
10922  * "escape({string}, {chars})" function
10923  */
10924     static void
10925 f_escape(typval_T *argvars, typval_T *rettv)
10926 {
10927     char_u	buf[NUMBUFLEN];
10928 
10929     rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]),
10930 					 get_tv_string_buf(&argvars[1], buf));
10931     rettv->v_type = VAR_STRING;
10932 }
10933 
10934 /*
10935  * "eval()" function
10936  */
10937     static void
10938 f_eval(typval_T *argvars, typval_T *rettv)
10939 {
10940     char_u	*s, *p;
10941 
10942     s = get_tv_string_chk(&argvars[0]);
10943     if (s != NULL)
10944 	s = skipwhite(s);
10945 
10946     p = s;
10947     if (s == NULL || eval1(&s, rettv, TRUE) == FAIL)
10948     {
10949 	if (p != NULL && !aborting())
10950 	    EMSG2(_(e_invexpr2), p);
10951 	need_clr_eos = FALSE;
10952 	rettv->v_type = VAR_NUMBER;
10953 	rettv->vval.v_number = 0;
10954     }
10955     else if (*s != NUL)
10956 	EMSG(_(e_trailing));
10957 }
10958 
10959 /*
10960  * "eventhandler()" function
10961  */
10962     static void
10963 f_eventhandler(typval_T *argvars UNUSED, typval_T *rettv)
10964 {
10965     rettv->vval.v_number = vgetc_busy;
10966 }
10967 
10968 /*
10969  * "executable()" function
10970  */
10971     static void
10972 f_executable(typval_T *argvars, typval_T *rettv)
10973 {
10974     char_u *name = get_tv_string(&argvars[0]);
10975 
10976     /* Check in $PATH and also check directly if there is a directory name. */
10977     rettv->vval.v_number = mch_can_exe(name, NULL, TRUE)
10978 		 || (gettail(name) != name && mch_can_exe(name, NULL, FALSE));
10979 }
10980 
10981 /*
10982  * "exepath()" function
10983  */
10984     static void
10985 f_exepath(typval_T *argvars, typval_T *rettv)
10986 {
10987     char_u *p = NULL;
10988 
10989     (void)mch_can_exe(get_tv_string(&argvars[0]), &p, TRUE);
10990     rettv->v_type = VAR_STRING;
10991     rettv->vval.v_string = p;
10992 }
10993 
10994 /*
10995  * "exists()" function
10996  */
10997     static void
10998 f_exists(typval_T *argvars, typval_T *rettv)
10999 {
11000     char_u	*p;
11001     char_u	*name;
11002     int		n = FALSE;
11003     int		len = 0;
11004 
11005     p = get_tv_string(&argvars[0]);
11006     if (*p == '$')			/* environment variable */
11007     {
11008 	/* first try "normal" environment variables (fast) */
11009 	if (mch_getenv(p + 1) != NULL)
11010 	    n = TRUE;
11011 	else
11012 	{
11013 	    /* try expanding things like $VIM and ${HOME} */
11014 	    p = expand_env_save(p);
11015 	    if (p != NULL && *p != '$')
11016 		n = TRUE;
11017 	    vim_free(p);
11018 	}
11019     }
11020     else if (*p == '&' || *p == '+')			/* option */
11021     {
11022 	n = (get_option_tv(&p, NULL, TRUE) == OK);
11023 	if (*skipwhite(p) != NUL)
11024 	    n = FALSE;			/* trailing garbage */
11025     }
11026     else if (*p == '*')			/* internal or user defined function */
11027     {
11028 	n = function_exists(p + 1);
11029     }
11030     else if (*p == ':')
11031     {
11032 	n = cmd_exists(p + 1);
11033     }
11034     else if (*p == '#')
11035     {
11036 #ifdef FEAT_AUTOCMD
11037 	if (p[1] == '#')
11038 	    n = autocmd_supported(p + 2);
11039 	else
11040 	    n = au_exists(p + 1);
11041 #endif
11042     }
11043     else				/* internal variable */
11044     {
11045 	char_u	    *tofree;
11046 	typval_T    tv;
11047 
11048 	/* get_name_len() takes care of expanding curly braces */
11049 	name = p;
11050 	len = get_name_len(&p, &tofree, TRUE, FALSE);
11051 	if (len > 0)
11052 	{
11053 	    if (tofree != NULL)
11054 		name = tofree;
11055 	    n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK);
11056 	    if (n)
11057 	    {
11058 		/* handle d.key, l[idx], f(expr) */
11059 		n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK);
11060 		if (n)
11061 		    clear_tv(&tv);
11062 	    }
11063 	}
11064 	if (*p != NUL)
11065 	    n = FALSE;
11066 
11067 	vim_free(tofree);
11068     }
11069 
11070     rettv->vval.v_number = n;
11071 }
11072 
11073 #ifdef FEAT_FLOAT
11074 /*
11075  * "exp()" function
11076  */
11077     static void
11078 f_exp(typval_T *argvars, typval_T *rettv)
11079 {
11080     float_T	f = 0.0;
11081 
11082     rettv->v_type = VAR_FLOAT;
11083     if (get_float_arg(argvars, &f) == OK)
11084 	rettv->vval.v_float = exp(f);
11085     else
11086 	rettv->vval.v_float = 0.0;
11087 }
11088 #endif
11089 
11090 /*
11091  * "expand()" function
11092  */
11093     static void
11094 f_expand(typval_T *argvars, typval_T *rettv)
11095 {
11096     char_u	*s;
11097     int		len;
11098     char_u	*errormsg;
11099     int		options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
11100     expand_T	xpc;
11101     int		error = FALSE;
11102     char_u	*result;
11103 
11104     rettv->v_type = VAR_STRING;
11105     if (argvars[1].v_type != VAR_UNKNOWN
11106 	    && argvars[2].v_type != VAR_UNKNOWN
11107 	    && get_tv_number_chk(&argvars[2], &error)
11108 	    && !error)
11109     {
11110 	rettv->v_type = VAR_LIST;
11111 	rettv->vval.v_list = NULL;
11112     }
11113 
11114     s = get_tv_string(&argvars[0]);
11115     if (*s == '%' || *s == '#' || *s == '<')
11116     {
11117 	++emsg_off;
11118 	result = eval_vars(s, s, &len, NULL, &errormsg, NULL);
11119 	--emsg_off;
11120 	if (rettv->v_type == VAR_LIST)
11121 	{
11122 	    if (rettv_list_alloc(rettv) != FAIL && result != NULL)
11123 		list_append_string(rettv->vval.v_list, result, -1);
11124 	    else
11125 		vim_free(result);
11126 	}
11127 	else
11128 	    rettv->vval.v_string = result;
11129     }
11130     else
11131     {
11132 	/* When the optional second argument is non-zero, don't remove matches
11133 	 * for 'wildignore' and don't put matches for 'suffixes' at the end. */
11134 	if (argvars[1].v_type != VAR_UNKNOWN
11135 				    && get_tv_number_chk(&argvars[1], &error))
11136 	    options |= WILD_KEEP_ALL;
11137 	if (!error)
11138 	{
11139 	    ExpandInit(&xpc);
11140 	    xpc.xp_context = EXPAND_FILES;
11141 	    if (p_wic)
11142 		options += WILD_ICASE;
11143 	    if (rettv->v_type == VAR_STRING)
11144 		rettv->vval.v_string = ExpandOne(&xpc, s, NULL,
11145 							   options, WILD_ALL);
11146 	    else if (rettv_list_alloc(rettv) != FAIL)
11147 	    {
11148 		int i;
11149 
11150 		ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP);
11151 		for (i = 0; i < xpc.xp_numfiles; i++)
11152 		    list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
11153 		ExpandCleanup(&xpc);
11154 	    }
11155 	}
11156 	else
11157 	    rettv->vval.v_string = NULL;
11158     }
11159 }
11160 
11161 /*
11162  * Go over all entries in "d2" and add them to "d1".
11163  * When "action" is "error" then a duplicate key is an error.
11164  * When "action" is "force" then a duplicate key is overwritten.
11165  * Otherwise duplicate keys are ignored ("action" is "keep").
11166  */
11167     void
11168 dict_extend(dict_T *d1, dict_T *d2, char_u *action)
11169 {
11170     dictitem_T	*di1;
11171     hashitem_T	*hi2;
11172     int		todo;
11173     char_u	*arg_errmsg = (char_u *)N_("extend() argument");
11174 
11175     todo = (int)d2->dv_hashtab.ht_used;
11176     for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2)
11177     {
11178 	if (!HASHITEM_EMPTY(hi2))
11179 	{
11180 	    --todo;
11181 	    di1 = dict_find(d1, hi2->hi_key, -1);
11182 	    if (d1->dv_scope != 0)
11183 	    {
11184 		/* Disallow replacing a builtin function in l: and g:.
11185 		 * Check the key to be valid when adding to any
11186 		 * scope. */
11187 		if (d1->dv_scope == VAR_DEF_SCOPE
11188 			&& HI2DI(hi2)->di_tv.v_type == VAR_FUNC
11189 			&& var_check_func_name(hi2->hi_key,
11190 							 di1 == NULL))
11191 		    break;
11192 		if (!valid_varname(hi2->hi_key))
11193 		    break;
11194 	    }
11195 	    if (di1 == NULL)
11196 	    {
11197 		di1 = dictitem_copy(HI2DI(hi2));
11198 		if (di1 != NULL && dict_add(d1, di1) == FAIL)
11199 		    dictitem_free(di1);
11200 	    }
11201 	    else if (*action == 'e')
11202 	    {
11203 		EMSG2(_("E737: Key already exists: %s"), hi2->hi_key);
11204 		break;
11205 	    }
11206 	    else if (*action == 'f' && HI2DI(hi2) != di1)
11207 	    {
11208 		if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, TRUE)
11209 		      || var_check_ro(di1->di_flags, arg_errmsg, TRUE))
11210 		    break;
11211 		clear_tv(&di1->di_tv);
11212 		copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv);
11213 	    }
11214 	}
11215     }
11216 }
11217 
11218 /*
11219  * "extend(list, list [, idx])" function
11220  * "extend(dict, dict [, action])" function
11221  */
11222     static void
11223 f_extend(typval_T *argvars, typval_T *rettv)
11224 {
11225     char_u      *arg_errmsg = (char_u *)N_("extend() argument");
11226 
11227     if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
11228     {
11229 	list_T		*l1, *l2;
11230 	listitem_T	*item;
11231 	long		before;
11232 	int		error = FALSE;
11233 
11234 	l1 = argvars[0].vval.v_list;
11235 	l2 = argvars[1].vval.v_list;
11236 	if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, TRUE)
11237 		&& l2 != NULL)
11238 	{
11239 	    if (argvars[2].v_type != VAR_UNKNOWN)
11240 	    {
11241 		before = get_tv_number_chk(&argvars[2], &error);
11242 		if (error)
11243 		    return;		/* type error; errmsg already given */
11244 
11245 		if (before == l1->lv_len)
11246 		    item = NULL;
11247 		else
11248 		{
11249 		    item = list_find(l1, before);
11250 		    if (item == NULL)
11251 		    {
11252 			EMSGN(_(e_listidx), before);
11253 			return;
11254 		    }
11255 		}
11256 	    }
11257 	    else
11258 		item = NULL;
11259 	    list_extend(l1, l2, item);
11260 
11261 	    copy_tv(&argvars[0], rettv);
11262 	}
11263     }
11264     else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
11265     {
11266 	dict_T	*d1, *d2;
11267 	char_u	*action;
11268 	int	i;
11269 
11270 	d1 = argvars[0].vval.v_dict;
11271 	d2 = argvars[1].vval.v_dict;
11272 	if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, TRUE)
11273 		&& d2 != NULL)
11274 	{
11275 	    /* Check the third argument. */
11276 	    if (argvars[2].v_type != VAR_UNKNOWN)
11277 	    {
11278 		static char *(av[]) = {"keep", "force", "error"};
11279 
11280 		action = get_tv_string_chk(&argvars[2]);
11281 		if (action == NULL)
11282 		    return;		/* type error; errmsg already given */
11283 		for (i = 0; i < 3; ++i)
11284 		    if (STRCMP(action, av[i]) == 0)
11285 			break;
11286 		if (i == 3)
11287 		{
11288 		    EMSG2(_(e_invarg2), action);
11289 		    return;
11290 		}
11291 	    }
11292 	    else
11293 		action = (char_u *)"force";
11294 
11295 	    dict_extend(d1, d2, action);
11296 
11297 	    copy_tv(&argvars[0], rettv);
11298 	}
11299     }
11300     else
11301 	EMSG2(_(e_listdictarg), "extend()");
11302 }
11303 
11304 /*
11305  * "feedkeys()" function
11306  */
11307     static void
11308 f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED)
11309 {
11310     int		remap = TRUE;
11311     int		insert = FALSE;
11312     char_u	*keys, *flags;
11313     char_u	nbuf[NUMBUFLEN];
11314     int		typed = FALSE;
11315     int		execute = FALSE;
11316     char_u	*keys_esc;
11317 
11318     /* This is not allowed in the sandbox.  If the commands would still be
11319      * executed in the sandbox it would be OK, but it probably happens later,
11320      * when "sandbox" is no longer set. */
11321     if (check_secure())
11322 	return;
11323 
11324     keys = get_tv_string(&argvars[0]);
11325 
11326     if (argvars[1].v_type != VAR_UNKNOWN)
11327     {
11328 	flags = get_tv_string_buf(&argvars[1], nbuf);
11329 	for ( ; *flags != NUL; ++flags)
11330 	{
11331 	    switch (*flags)
11332 	    {
11333 		case 'n': remap = FALSE; break;
11334 		case 'm': remap = TRUE; break;
11335 		case 't': typed = TRUE; break;
11336 		case 'i': insert = TRUE; break;
11337 		case 'x': execute = TRUE; break;
11338 	    }
11339 	}
11340     }
11341 
11342     if (*keys != NUL || execute)
11343     {
11344 	/* Need to escape K_SPECIAL and CSI before putting the string in the
11345 	 * typeahead buffer. */
11346 	keys_esc = vim_strsave_escape_csi(keys);
11347 	if (keys_esc != NULL)
11348 	{
11349 	    ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
11350 				  insert ? 0 : typebuf.tb_len, !typed, FALSE);
11351 	    vim_free(keys_esc);
11352 	    if (vgetc_busy)
11353 		typebuf_was_filled = TRUE;
11354 	    if (execute)
11355 	    {
11356 		int save_msg_scroll = msg_scroll;
11357 
11358 		/* Avoid a 1 second delay when the keys start Insert mode. */
11359 		msg_scroll = FALSE;
11360 		exec_normal(TRUE);
11361 		msg_scroll |= save_msg_scroll;
11362 	    }
11363 	}
11364     }
11365 }
11366 
11367 /*
11368  * "filereadable()" function
11369  */
11370     static void
11371 f_filereadable(typval_T *argvars, typval_T *rettv)
11372 {
11373     int		fd;
11374     char_u	*p;
11375     int		n;
11376 
11377 #ifndef O_NONBLOCK
11378 # define O_NONBLOCK 0
11379 #endif
11380     p = get_tv_string(&argvars[0]);
11381     if (*p && !mch_isdir(p) && (fd = mch_open((char *)p,
11382 					      O_RDONLY | O_NONBLOCK, 0)) >= 0)
11383     {
11384 	n = TRUE;
11385 	close(fd);
11386     }
11387     else
11388 	n = FALSE;
11389 
11390     rettv->vval.v_number = n;
11391 }
11392 
11393 /*
11394  * Return 0 for not writable, 1 for writable file, 2 for a dir which we have
11395  * rights to write into.
11396  */
11397     static void
11398 f_filewritable(typval_T *argvars, typval_T *rettv)
11399 {
11400     rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
11401 }
11402 
11403     static void
11404 findfilendir(
11405     typval_T	*argvars UNUSED,
11406     typval_T	*rettv,
11407     int		find_what UNUSED)
11408 {
11409 #ifdef FEAT_SEARCHPATH
11410     char_u	*fname;
11411     char_u	*fresult = NULL;
11412     char_u	*path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
11413     char_u	*p;
11414     char_u	pathbuf[NUMBUFLEN];
11415     int		count = 1;
11416     int		first = TRUE;
11417     int		error = FALSE;
11418 #endif
11419 
11420     rettv->vval.v_string = NULL;
11421     rettv->v_type = VAR_STRING;
11422 
11423 #ifdef FEAT_SEARCHPATH
11424     fname = get_tv_string(&argvars[0]);
11425 
11426     if (argvars[1].v_type != VAR_UNKNOWN)
11427     {
11428 	p = get_tv_string_buf_chk(&argvars[1], pathbuf);
11429 	if (p == NULL)
11430 	    error = TRUE;
11431 	else
11432 	{
11433 	    if (*p != NUL)
11434 		path = p;
11435 
11436 	    if (argvars[2].v_type != VAR_UNKNOWN)
11437 		count = get_tv_number_chk(&argvars[2], &error);
11438 	}
11439     }
11440 
11441     if (count < 0 && rettv_list_alloc(rettv) == FAIL)
11442 	error = TRUE;
11443 
11444     if (*fname != NUL && !error)
11445     {
11446 	do
11447 	{
11448 	    if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST)
11449 		vim_free(fresult);
11450 	    fresult = find_file_in_path_option(first ? fname : NULL,
11451 					       first ? (int)STRLEN(fname) : 0,
11452 					0, first, path,
11453 					find_what,
11454 					curbuf->b_ffname,
11455 					find_what == FINDFILE_DIR
11456 					    ? (char_u *)"" : curbuf->b_p_sua);
11457 	    first = FALSE;
11458 
11459 	    if (fresult != NULL && rettv->v_type == VAR_LIST)
11460 		list_append_string(rettv->vval.v_list, fresult, -1);
11461 
11462 	} while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL);
11463     }
11464 
11465     if (rettv->v_type == VAR_STRING)
11466 	rettv->vval.v_string = fresult;
11467 #endif
11468 }
11469 
11470 static void filter_map(typval_T *argvars, typval_T *rettv, int map);
11471 static int filter_map_one(typval_T *tv, char_u *expr, int map, int *remp);
11472 
11473 /*
11474  * Implementation of map() and filter().
11475  */
11476     static void
11477 filter_map(typval_T *argvars, typval_T *rettv, int map)
11478 {
11479     char_u	buf[NUMBUFLEN];
11480     char_u	*expr;
11481     listitem_T	*li, *nli;
11482     list_T	*l = NULL;
11483     dictitem_T	*di;
11484     hashtab_T	*ht;
11485     hashitem_T	*hi;
11486     dict_T	*d = NULL;
11487     typval_T	save_val;
11488     typval_T	save_key;
11489     int		rem;
11490     int		todo;
11491     char_u	*ermsg = (char_u *)(map ? "map()" : "filter()");
11492     char_u	*arg_errmsg = (char_u *)(map ? N_("map() argument")
11493 				   : N_("filter() argument"));
11494     int		save_did_emsg;
11495     int		idx = 0;
11496 
11497     if (argvars[0].v_type == VAR_LIST)
11498     {
11499 	if ((l = argvars[0].vval.v_list) == NULL
11500 	      || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TRUE)))
11501 	    return;
11502     }
11503     else if (argvars[0].v_type == VAR_DICT)
11504     {
11505 	if ((d = argvars[0].vval.v_dict) == NULL
11506 	      || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TRUE)))
11507 	    return;
11508     }
11509     else
11510     {
11511 	EMSG2(_(e_listdictarg), ermsg);
11512 	return;
11513     }
11514 
11515     expr = get_tv_string_buf_chk(&argvars[1], buf);
11516     /* On type errors, the preceding call has already displayed an error
11517      * message.  Avoid a misleading error message for an empty string that
11518      * was not passed as argument. */
11519     if (expr != NULL)
11520     {
11521 	prepare_vimvar(VV_VAL, &save_val);
11522 	expr = skipwhite(expr);
11523 
11524 	/* We reset "did_emsg" to be able to detect whether an error
11525 	 * occurred during evaluation of the expression. */
11526 	save_did_emsg = did_emsg;
11527 	did_emsg = FALSE;
11528 
11529 	prepare_vimvar(VV_KEY, &save_key);
11530 	if (argvars[0].v_type == VAR_DICT)
11531 	{
11532 	    vimvars[VV_KEY].vv_type = VAR_STRING;
11533 
11534 	    ht = &d->dv_hashtab;
11535 	    hash_lock(ht);
11536 	    todo = (int)ht->ht_used;
11537 	    for (hi = ht->ht_array; todo > 0; ++hi)
11538 	    {
11539 		if (!HASHITEM_EMPTY(hi))
11540 		{
11541 		    int r;
11542 
11543 		    --todo;
11544 		    di = HI2DI(hi);
11545 		    if (map &&
11546 			    (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TRUE)
11547 			    || var_check_ro(di->di_flags, arg_errmsg, TRUE)))
11548 			break;
11549 		    vimvars[VV_KEY].vv_str = vim_strsave(di->di_key);
11550 		    r = filter_map_one(&di->di_tv, expr, map, &rem);
11551 		    clear_tv(&vimvars[VV_KEY].vv_tv);
11552 		    if (r == FAIL || did_emsg)
11553 			break;
11554 		    if (!map && rem)
11555 		    {
11556 			if (var_check_fixed(di->di_flags, arg_errmsg, TRUE)
11557 			    || var_check_ro(di->di_flags, arg_errmsg, TRUE))
11558 			    break;
11559 			dictitem_remove(d, di);
11560 		    }
11561 		}
11562 	    }
11563 	    hash_unlock(ht);
11564 	}
11565 	else
11566 	{
11567 	    vimvars[VV_KEY].vv_type = VAR_NUMBER;
11568 
11569 	    for (li = l->lv_first; li != NULL; li = nli)
11570 	    {
11571 		if (map && tv_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE))
11572 		    break;
11573 		nli = li->li_next;
11574 		vimvars[VV_KEY].vv_nr = idx;
11575 		if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
11576 								  || did_emsg)
11577 		    break;
11578 		if (!map && rem)
11579 		    listitem_remove(l, li);
11580 		++idx;
11581 	    }
11582 	}
11583 
11584 	restore_vimvar(VV_KEY, &save_key);
11585 	restore_vimvar(VV_VAL, &save_val);
11586 
11587 	did_emsg |= save_did_emsg;
11588     }
11589 
11590     copy_tv(&argvars[0], rettv);
11591 }
11592 
11593     static int
11594 filter_map_one(typval_T *tv, char_u *expr, int map, int *remp)
11595 {
11596     typval_T	rettv;
11597     char_u	*s;
11598     int		retval = FAIL;
11599 
11600     copy_tv(tv, &vimvars[VV_VAL].vv_tv);
11601     s = expr;
11602     if (eval1(&s, &rettv, TRUE) == FAIL)
11603 	goto theend;
11604     if (*s != NUL)  /* check for trailing chars after expr */
11605     {
11606 	EMSG2(_(e_invexpr2), s);
11607 	clear_tv(&rettv);
11608 	goto theend;
11609     }
11610     if (map)
11611     {
11612 	/* map(): replace the list item value */
11613 	clear_tv(tv);
11614 	rettv.v_lock = 0;
11615 	*tv = rettv;
11616     }
11617     else
11618     {
11619 	int	    error = FALSE;
11620 
11621 	/* filter(): when expr is zero remove the item */
11622 	*remp = (get_tv_number_chk(&rettv, &error) == 0);
11623 	clear_tv(&rettv);
11624 	/* On type error, nothing has been removed; return FAIL to stop the
11625 	 * loop.  The error message was given by get_tv_number_chk(). */
11626 	if (error)
11627 	    goto theend;
11628     }
11629     retval = OK;
11630 theend:
11631     clear_tv(&vimvars[VV_VAL].vv_tv);
11632     return retval;
11633 }
11634 
11635 /*
11636  * "filter()" function
11637  */
11638     static void
11639 f_filter(typval_T *argvars, typval_T *rettv)
11640 {
11641     filter_map(argvars, rettv, FALSE);
11642 }
11643 
11644 /*
11645  * "finddir({fname}[, {path}[, {count}]])" function
11646  */
11647     static void
11648 f_finddir(typval_T *argvars, typval_T *rettv)
11649 {
11650     findfilendir(argvars, rettv, FINDFILE_DIR);
11651 }
11652 
11653 /*
11654  * "findfile({fname}[, {path}[, {count}]])" function
11655  */
11656     static void
11657 f_findfile(typval_T *argvars, typval_T *rettv)
11658 {
11659     findfilendir(argvars, rettv, FINDFILE_FILE);
11660 }
11661 
11662 #ifdef FEAT_FLOAT
11663 /*
11664  * "float2nr({float})" function
11665  */
11666     static void
11667 f_float2nr(typval_T *argvars, typval_T *rettv)
11668 {
11669     float_T	f = 0.0;
11670 
11671     if (get_float_arg(argvars, &f) == OK)
11672     {
11673 	if (f < -0x7fffffff)
11674 	    rettv->vval.v_number = -0x7fffffff;
11675 	else if (f > 0x7fffffff)
11676 	    rettv->vval.v_number = 0x7fffffff;
11677 	else
11678 	    rettv->vval.v_number = (varnumber_T)f;
11679     }
11680 }
11681 
11682 /*
11683  * "floor({float})" function
11684  */
11685     static void
11686 f_floor(typval_T *argvars, typval_T *rettv)
11687 {
11688     float_T	f = 0.0;
11689 
11690     rettv->v_type = VAR_FLOAT;
11691     if (get_float_arg(argvars, &f) == OK)
11692 	rettv->vval.v_float = floor(f);
11693     else
11694 	rettv->vval.v_float = 0.0;
11695 }
11696 
11697 /*
11698  * "fmod()" function
11699  */
11700     static void
11701 f_fmod(typval_T *argvars, typval_T *rettv)
11702 {
11703     float_T	fx = 0.0, fy = 0.0;
11704 
11705     rettv->v_type = VAR_FLOAT;
11706     if (get_float_arg(argvars, &fx) == OK
11707 				     && get_float_arg(&argvars[1], &fy) == OK)
11708 	rettv->vval.v_float = fmod(fx, fy);
11709     else
11710 	rettv->vval.v_float = 0.0;
11711 }
11712 #endif
11713 
11714 /*
11715  * "fnameescape({string})" function
11716  */
11717     static void
11718 f_fnameescape(typval_T *argvars, typval_T *rettv)
11719 {
11720     rettv->vval.v_string = vim_strsave_fnameescape(
11721 					   get_tv_string(&argvars[0]), FALSE);
11722     rettv->v_type = VAR_STRING;
11723 }
11724 
11725 /*
11726  * "fnamemodify({fname}, {mods})" function
11727  */
11728     static void
11729 f_fnamemodify(typval_T *argvars, typval_T *rettv)
11730 {
11731     char_u	*fname;
11732     char_u	*mods;
11733     int		usedlen = 0;
11734     int		len;
11735     char_u	*fbuf = NULL;
11736     char_u	buf[NUMBUFLEN];
11737 
11738     fname = get_tv_string_chk(&argvars[0]);
11739     mods = get_tv_string_buf_chk(&argvars[1], buf);
11740     if (fname == NULL || mods == NULL)
11741 	fname = NULL;
11742     else
11743     {
11744 	len = (int)STRLEN(fname);
11745 	(void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
11746     }
11747 
11748     rettv->v_type = VAR_STRING;
11749     if (fname == NULL)
11750 	rettv->vval.v_string = NULL;
11751     else
11752 	rettv->vval.v_string = vim_strnsave(fname, len);
11753     vim_free(fbuf);
11754 }
11755 
11756 static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end);
11757 
11758 /*
11759  * "foldclosed()" function
11760  */
11761     static void
11762 foldclosed_both(
11763     typval_T	*argvars UNUSED,
11764     typval_T	*rettv,
11765     int		end UNUSED)
11766 {
11767 #ifdef FEAT_FOLDING
11768     linenr_T	lnum;
11769     linenr_T	first, last;
11770 
11771     lnum = get_tv_lnum(argvars);
11772     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
11773     {
11774 	if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL))
11775 	{
11776 	    if (end)
11777 		rettv->vval.v_number = (varnumber_T)last;
11778 	    else
11779 		rettv->vval.v_number = (varnumber_T)first;
11780 	    return;
11781 	}
11782     }
11783 #endif
11784     rettv->vval.v_number = -1;
11785 }
11786 
11787 /*
11788  * "foldclosed()" function
11789  */
11790     static void
11791 f_foldclosed(typval_T *argvars, typval_T *rettv)
11792 {
11793     foldclosed_both(argvars, rettv, FALSE);
11794 }
11795 
11796 /*
11797  * "foldclosedend()" function
11798  */
11799     static void
11800 f_foldclosedend(typval_T *argvars, typval_T *rettv)
11801 {
11802     foldclosed_both(argvars, rettv, TRUE);
11803 }
11804 
11805 /*
11806  * "foldlevel()" function
11807  */
11808     static void
11809 f_foldlevel(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
11810 {
11811 #ifdef FEAT_FOLDING
11812     linenr_T	lnum;
11813 
11814     lnum = get_tv_lnum(argvars);
11815     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
11816 	rettv->vval.v_number = foldLevel(lnum);
11817 #endif
11818 }
11819 
11820 /*
11821  * "foldtext()" function
11822  */
11823     static void
11824 f_foldtext(typval_T *argvars UNUSED, typval_T *rettv)
11825 {
11826 #ifdef FEAT_FOLDING
11827     linenr_T	lnum;
11828     char_u	*s;
11829     char_u	*r;
11830     int		len;
11831     char	*txt;
11832 #endif
11833 
11834     rettv->v_type = VAR_STRING;
11835     rettv->vval.v_string = NULL;
11836 #ifdef FEAT_FOLDING
11837     if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0
11838 	    && (linenr_T)vimvars[VV_FOLDEND].vv_nr
11839 						 <= curbuf->b_ml.ml_line_count
11840 	    && vimvars[VV_FOLDDASHES].vv_str != NULL)
11841     {
11842 	/* Find first non-empty line in the fold. */
11843 	lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr;
11844 	while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr)
11845 	{
11846 	    if (!linewhite(lnum))
11847 		break;
11848 	    ++lnum;
11849 	}
11850 
11851 	/* Find interesting text in this line. */
11852 	s = skipwhite(ml_get(lnum));
11853 	/* skip C comment-start */
11854 	if (s[0] == '/' && (s[1] == '*' || s[1] == '/'))
11855 	{
11856 	    s = skipwhite(s + 2);
11857 	    if (*skipwhite(s) == NUL
11858 			    && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr)
11859 	    {
11860 		s = skipwhite(ml_get(lnum + 1));
11861 		if (*s == '*')
11862 		    s = skipwhite(s + 1);
11863 	    }
11864 	}
11865 	txt = _("+-%s%3ld lines: ");
11866 	r = alloc((unsigned)(STRLEN(txt)
11867 		    + STRLEN(vimvars[VV_FOLDDASHES].vv_str)    /* for %s */
11868 		    + 20				    /* for %3ld */
11869 		    + STRLEN(s)));			    /* concatenated */
11870 	if (r != NULL)
11871 	{
11872 	    sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str,
11873 		    (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr
11874 				- (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1));
11875 	    len = (int)STRLEN(r);
11876 	    STRCAT(r, s);
11877 	    /* remove 'foldmarker' and 'commentstring' */
11878 	    foldtext_cleanup(r + len);
11879 	    rettv->vval.v_string = r;
11880 	}
11881     }
11882 #endif
11883 }
11884 
11885 /*
11886  * "foldtextresult(lnum)" function
11887  */
11888     static void
11889 f_foldtextresult(typval_T *argvars UNUSED, typval_T *rettv)
11890 {
11891 #ifdef FEAT_FOLDING
11892     linenr_T	lnum;
11893     char_u	*text;
11894     char_u	buf[51];
11895     foldinfo_T  foldinfo;
11896     int		fold_count;
11897 #endif
11898 
11899     rettv->v_type = VAR_STRING;
11900     rettv->vval.v_string = NULL;
11901 #ifdef FEAT_FOLDING
11902     lnum = get_tv_lnum(argvars);
11903     /* treat illegal types and illegal string values for {lnum} the same */
11904     if (lnum < 0)
11905 	lnum = 0;
11906     fold_count = foldedCount(curwin, lnum, &foldinfo);
11907     if (fold_count > 0)
11908     {
11909 	text = get_foldtext(curwin, lnum, lnum + fold_count - 1,
11910 							      &foldinfo, buf);
11911 	if (text == buf)
11912 	    text = vim_strsave(text);
11913 	rettv->vval.v_string = text;
11914     }
11915 #endif
11916 }
11917 
11918 /*
11919  * "foreground()" function
11920  */
11921     static void
11922 f_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
11923 {
11924 #ifdef FEAT_GUI
11925     if (gui.in_use)
11926 	gui_mch_set_foreground();
11927 #else
11928 # ifdef WIN32
11929     win32_set_foreground();
11930 # endif
11931 #endif
11932 }
11933 
11934 /*
11935  * "function()" function
11936  */
11937     static void
11938 f_function(typval_T *argvars, typval_T *rettv)
11939 {
11940     char_u	*s;
11941     char_u	*name;
11942     int		use_string = FALSE;
11943     partial_T   *arg_pt = NULL;
11944 
11945     if (argvars[0].v_type == VAR_FUNC)
11946     {
11947 	/* function(MyFunc, [arg], dict) */
11948 	s = argvars[0].vval.v_string;
11949     }
11950     else if (argvars[0].v_type == VAR_PARTIAL
11951 					 && argvars[0].vval.v_partial != NULL)
11952     {
11953 	/* function(dict.MyFunc, [arg]) */
11954 	arg_pt = argvars[0].vval.v_partial;
11955 	s = arg_pt->pt_name;
11956     }
11957     else
11958     {
11959 	/* function('MyFunc', [arg], dict) */
11960 	s = get_tv_string(&argvars[0]);
11961 	use_string = TRUE;
11962     }
11963 
11964     if (s == NULL || *s == NUL || (use_string && VIM_ISDIGIT(*s)))
11965 	EMSG2(_(e_invarg2), s);
11966     /* Don't check an autoload name for existence here. */
11967     else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL
11968 						       && !function_exists(s))
11969 	EMSG2(_("E700: Unknown function: %s"), s);
11970     else
11971     {
11972 	int	dict_idx = 0;
11973 	int	arg_idx = 0;
11974 	list_T	*list = NULL;
11975 
11976 	if (STRNCMP(s, "s:", 2) == 0 || STRNCMP(s, "<SID>", 5) == 0)
11977 	{
11978 	    char	sid_buf[25];
11979 	    int		off = *s == 's' ? 2 : 5;
11980 
11981 	    /* Expand s: and <SID> into <SNR>nr_, so that the function can
11982 	     * also be called from another script. Using trans_function_name()
11983 	     * would also work, but some plugins depend on the name being
11984 	     * printable text. */
11985 	    sprintf(sid_buf, "<SNR>%ld_", (long)current_SID);
11986 	    name = alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1));
11987 	    if (name != NULL)
11988 	    {
11989 		STRCPY(name, sid_buf);
11990 		STRCAT(name, s + off);
11991 	    }
11992 	}
11993 	else
11994 	    name = vim_strsave(s);
11995 
11996 	if (argvars[1].v_type != VAR_UNKNOWN)
11997 	{
11998 	    if (argvars[2].v_type != VAR_UNKNOWN)
11999 	    {
12000 		/* function(name, [args], dict) */
12001 		arg_idx = 1;
12002 		dict_idx = 2;
12003 	    }
12004 	    else if (argvars[1].v_type == VAR_DICT)
12005 		/* function(name, dict) */
12006 		dict_idx = 1;
12007 	    else
12008 		/* function(name, [args]) */
12009 		arg_idx = 1;
12010 	    if (dict_idx > 0)
12011 	    {
12012 		if (argvars[dict_idx].v_type != VAR_DICT)
12013 		{
12014 		    EMSG(_("E922: expected a dict"));
12015 		    vim_free(name);
12016 		    return;
12017 		}
12018 		if (argvars[dict_idx].vval.v_dict == NULL)
12019 		    dict_idx = 0;
12020 	    }
12021 	    if (arg_idx > 0)
12022 	    {
12023 		if (argvars[arg_idx].v_type != VAR_LIST)
12024 		{
12025 		    EMSG(_("E923: Second argument of function() must be a list or a dict"));
12026 		    vim_free(name);
12027 		    return;
12028 		}
12029 		list = argvars[arg_idx].vval.v_list;
12030 		if (list == NULL || list->lv_len == 0)
12031 		    arg_idx = 0;
12032 	    }
12033 	}
12034 	if (dict_idx > 0 || arg_idx > 0 || arg_pt != NULL)
12035 	{
12036 	    partial_T	*pt = (partial_T *)alloc_clear(sizeof(partial_T));
12037 
12038 	    /* result is a VAR_PARTIAL */
12039 	    if (pt == NULL)
12040 		vim_free(name);
12041 	    else
12042 	    {
12043 		if (arg_idx > 0 || (arg_pt != NULL && arg_pt->pt_argc > 0))
12044 		{
12045 		    listitem_T	*li;
12046 		    int		i = 0;
12047 		    int		arg_len = 0;
12048 		    int		lv_len = 0;
12049 
12050 		    if (arg_pt != NULL)
12051 			arg_len = arg_pt->pt_argc;
12052 		    if (list != NULL)
12053 			lv_len = list->lv_len;
12054 		    pt->pt_argc = arg_len + lv_len;
12055 		    pt->pt_argv = (typval_T *)alloc(
12056 					      sizeof(typval_T) * pt->pt_argc);
12057 		    if (pt->pt_argv == NULL)
12058 		    {
12059 			vim_free(pt);
12060 			vim_free(name);
12061 			return;
12062 		    }
12063 		    else
12064 		    {
12065 			for (i = 0; i < arg_len; i++)
12066 			    copy_tv(&arg_pt->pt_argv[i], &pt->pt_argv[i]);
12067 			if (lv_len > 0)
12068 			    for (li = list->lv_first; li != NULL;
12069 							     li = li->li_next)
12070 				copy_tv(&li->li_tv, &pt->pt_argv[i++]);
12071 		    }
12072 		}
12073 
12074 		/* For "function(dict.func, [], dict)" and "func" is a partial
12075 		 * use "dict".  That is backwards compatible. */
12076 		if (dict_idx > 0)
12077 		{
12078 		    pt->pt_dict = argvars[dict_idx].vval.v_dict;
12079 		    ++pt->pt_dict->dv_refcount;
12080 		}
12081 		else if (arg_pt != NULL)
12082 		{
12083 		    pt->pt_dict = arg_pt->pt_dict;
12084 		    if (pt->pt_dict != NULL)
12085 			++pt->pt_dict->dv_refcount;
12086 		}
12087 
12088 		pt->pt_refcount = 1;
12089 		pt->pt_name = name;
12090 		func_ref(pt->pt_name);
12091 	    }
12092 	    rettv->v_type = VAR_PARTIAL;
12093 	    rettv->vval.v_partial = pt;
12094 	}
12095 	else
12096 	{
12097 	    /* result is a VAR_FUNC */
12098 	    rettv->v_type = VAR_FUNC;
12099 	    rettv->vval.v_string = name;
12100 	    func_ref(name);
12101 	}
12102     }
12103 }
12104 
12105 /*
12106  * "garbagecollect()" function
12107  */
12108     static void
12109 f_garbagecollect(typval_T *argvars, typval_T *rettv UNUSED)
12110 {
12111     /* This is postponed until we are back at the toplevel, because we may be
12112      * using Lists and Dicts internally.  E.g.: ":echo [garbagecollect()]". */
12113     want_garbage_collect = TRUE;
12114 
12115     if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1)
12116 	garbage_collect_at_exit = TRUE;
12117 }
12118 
12119 /*
12120  * "get()" function
12121  */
12122     static void
12123 f_get(typval_T *argvars, typval_T *rettv)
12124 {
12125     listitem_T	*li;
12126     list_T	*l;
12127     dictitem_T	*di;
12128     dict_T	*d;
12129     typval_T	*tv = NULL;
12130 
12131     if (argvars[0].v_type == VAR_LIST)
12132     {
12133 	if ((l = argvars[0].vval.v_list) != NULL)
12134 	{
12135 	    int		error = FALSE;
12136 
12137 	    li = list_find(l, get_tv_number_chk(&argvars[1], &error));
12138 	    if (!error && li != NULL)
12139 		tv = &li->li_tv;
12140 	}
12141     }
12142     else if (argvars[0].v_type == VAR_DICT)
12143     {
12144 	if ((d = argvars[0].vval.v_dict) != NULL)
12145 	{
12146 	    di = dict_find(d, get_tv_string(&argvars[1]), -1);
12147 	    if (di != NULL)
12148 		tv = &di->di_tv;
12149 	}
12150     }
12151     else
12152 	EMSG2(_(e_listdictarg), "get()");
12153 
12154     if (tv == NULL)
12155     {
12156 	if (argvars[2].v_type != VAR_UNKNOWN)
12157 	    copy_tv(&argvars[2], rettv);
12158     }
12159     else
12160 	copy_tv(tv, rettv);
12161 }
12162 
12163 static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv);
12164 
12165 /*
12166  * Get line or list of lines from buffer "buf" into "rettv".
12167  * Return a range (from start to end) of lines in rettv from the specified
12168  * buffer.
12169  * If 'retlist' is TRUE, then the lines are returned as a Vim List.
12170  */
12171     static void
12172 get_buffer_lines(
12173     buf_T	*buf,
12174     linenr_T	start,
12175     linenr_T	end,
12176     int		retlist,
12177     typval_T	*rettv)
12178 {
12179     char_u	*p;
12180 
12181     rettv->v_type = VAR_STRING;
12182     rettv->vval.v_string = NULL;
12183     if (retlist && rettv_list_alloc(rettv) == FAIL)
12184 	return;
12185 
12186     if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0)
12187 	return;
12188 
12189     if (!retlist)
12190     {
12191 	if (start >= 1 && start <= buf->b_ml.ml_line_count)
12192 	    p = ml_get_buf(buf, start, FALSE);
12193 	else
12194 	    p = (char_u *)"";
12195 	rettv->vval.v_string = vim_strsave(p);
12196     }
12197     else
12198     {
12199 	if (end < start)
12200 	    return;
12201 
12202 	if (start < 1)
12203 	    start = 1;
12204 	if (end > buf->b_ml.ml_line_count)
12205 	    end = buf->b_ml.ml_line_count;
12206 	while (start <= end)
12207 	    if (list_append_string(rettv->vval.v_list,
12208 				 ml_get_buf(buf, start++, FALSE), -1) == FAIL)
12209 		break;
12210     }
12211 }
12212 
12213 /*
12214  * "getbufline()" function
12215  */
12216     static void
12217 f_getbufline(typval_T *argvars, typval_T *rettv)
12218 {
12219     linenr_T	lnum;
12220     linenr_T	end;
12221     buf_T	*buf;
12222 
12223     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
12224     ++emsg_off;
12225     buf = get_buf_tv(&argvars[0], FALSE);
12226     --emsg_off;
12227 
12228     lnum = get_tv_lnum_buf(&argvars[1], buf);
12229     if (argvars[2].v_type == VAR_UNKNOWN)
12230 	end = lnum;
12231     else
12232 	end = get_tv_lnum_buf(&argvars[2], buf);
12233 
12234     get_buffer_lines(buf, lnum, end, TRUE, rettv);
12235 }
12236 
12237 /*
12238  * "getbufvar()" function
12239  */
12240     static void
12241 f_getbufvar(typval_T *argvars, typval_T *rettv)
12242 {
12243     buf_T	*buf;
12244     buf_T	*save_curbuf;
12245     char_u	*varname;
12246     dictitem_T	*v;
12247     int		done = FALSE;
12248 
12249     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
12250     varname = get_tv_string_chk(&argvars[1]);
12251     ++emsg_off;
12252     buf = get_buf_tv(&argvars[0], FALSE);
12253 
12254     rettv->v_type = VAR_STRING;
12255     rettv->vval.v_string = NULL;
12256 
12257     if (buf != NULL && varname != NULL)
12258     {
12259 	/* set curbuf to be our buf, temporarily */
12260 	save_curbuf = curbuf;
12261 	curbuf = buf;
12262 
12263 	if (*varname == '&')	/* buffer-local-option */
12264 	{
12265 	    if (get_option_tv(&varname, rettv, TRUE) == OK)
12266 		done = TRUE;
12267 	}
12268 	else if (STRCMP(varname, "changedtick") == 0)
12269 	{
12270 	    rettv->v_type = VAR_NUMBER;
12271 	    rettv->vval.v_number = curbuf->b_changedtick;
12272 	    done = TRUE;
12273 	}
12274 	else
12275 	{
12276 	    /* Look up the variable. */
12277 	    /* Let getbufvar({nr}, "") return the "b:" dictionary. */
12278 	    v = find_var_in_ht(&curbuf->b_vars->dv_hashtab,
12279 							 'b', varname, FALSE);
12280 	    if (v != NULL)
12281 	    {
12282 		copy_tv(&v->di_tv, rettv);
12283 		done = TRUE;
12284 	    }
12285 	}
12286 
12287 	/* restore previous notion of curbuf */
12288 	curbuf = save_curbuf;
12289     }
12290 
12291     if (!done && argvars[2].v_type != VAR_UNKNOWN)
12292 	/* use the default value */
12293 	copy_tv(&argvars[2], rettv);
12294 
12295     --emsg_off;
12296 }
12297 
12298 /*
12299  * "getchar()" function
12300  */
12301     static void
12302 f_getchar(typval_T *argvars, typval_T *rettv)
12303 {
12304     varnumber_T		n;
12305     int			error = FALSE;
12306 
12307     /* Position the cursor.  Needed after a message that ends in a space. */
12308     windgoto(msg_row, msg_col);
12309 
12310     ++no_mapping;
12311     ++allow_keys;
12312     for (;;)
12313     {
12314 	if (argvars[0].v_type == VAR_UNKNOWN)
12315 	    /* getchar(): blocking wait. */
12316 	    n = safe_vgetc();
12317 	else if (get_tv_number_chk(&argvars[0], &error) == 1)
12318 	    /* getchar(1): only check if char avail */
12319 	    n = vpeekc_any();
12320 	else if (error || vpeekc_any() == NUL)
12321 	    /* illegal argument or getchar(0) and no char avail: return zero */
12322 	    n = 0;
12323 	else
12324 	    /* getchar(0) and char avail: return char */
12325 	    n = safe_vgetc();
12326 
12327 	if (n == K_IGNORE)
12328 	    continue;
12329 	break;
12330     }
12331     --no_mapping;
12332     --allow_keys;
12333 
12334     vimvars[VV_MOUSE_WIN].vv_nr = 0;
12335     vimvars[VV_MOUSE_LNUM].vv_nr = 0;
12336     vimvars[VV_MOUSE_COL].vv_nr = 0;
12337 
12338     rettv->vval.v_number = n;
12339     if (IS_SPECIAL(n) || mod_mask != 0)
12340     {
12341 	char_u		temp[10];   /* modifier: 3, mbyte-char: 6, NUL: 1 */
12342 	int		i = 0;
12343 
12344 	/* Turn a special key into three bytes, plus modifier. */
12345 	if (mod_mask != 0)
12346 	{
12347 	    temp[i++] = K_SPECIAL;
12348 	    temp[i++] = KS_MODIFIER;
12349 	    temp[i++] = mod_mask;
12350 	}
12351 	if (IS_SPECIAL(n))
12352 	{
12353 	    temp[i++] = K_SPECIAL;
12354 	    temp[i++] = K_SECOND(n);
12355 	    temp[i++] = K_THIRD(n);
12356 	}
12357 #ifdef FEAT_MBYTE
12358 	else if (has_mbyte)
12359 	    i += (*mb_char2bytes)(n, temp + i);
12360 #endif
12361 	else
12362 	    temp[i++] = n;
12363 	temp[i++] = NUL;
12364 	rettv->v_type = VAR_STRING;
12365 	rettv->vval.v_string = vim_strsave(temp);
12366 
12367 #ifdef FEAT_MOUSE
12368 	if (is_mouse_key(n))
12369 	{
12370 	    int		row = mouse_row;
12371 	    int		col = mouse_col;
12372 	    win_T	*win;
12373 	    linenr_T	lnum;
12374 # ifdef FEAT_WINDOWS
12375 	    win_T	*wp;
12376 # endif
12377 	    int		winnr = 1;
12378 
12379 	    if (row >= 0 && col >= 0)
12380 	    {
12381 		/* Find the window at the mouse coordinates and compute the
12382 		 * text position. */
12383 		win = mouse_find_win(&row, &col);
12384 		(void)mouse_comp_pos(win, &row, &col, &lnum);
12385 # ifdef FEAT_WINDOWS
12386 		for (wp = firstwin; wp != win; wp = wp->w_next)
12387 		    ++winnr;
12388 # endif
12389 		vimvars[VV_MOUSE_WIN].vv_nr = winnr;
12390 		vimvars[VV_MOUSE_LNUM].vv_nr = lnum;
12391 		vimvars[VV_MOUSE_COL].vv_nr = col + 1;
12392 	    }
12393 	}
12394 #endif
12395     }
12396 }
12397 
12398 /*
12399  * "getcharmod()" function
12400  */
12401     static void
12402 f_getcharmod(typval_T *argvars UNUSED, typval_T *rettv)
12403 {
12404     rettv->vval.v_number = mod_mask;
12405 }
12406 
12407 /*
12408  * "getcharsearch()" function
12409  */
12410     static void
12411 f_getcharsearch(typval_T *argvars UNUSED, typval_T *rettv)
12412 {
12413     if (rettv_dict_alloc(rettv) != FAIL)
12414     {
12415 	dict_T *dict = rettv->vval.v_dict;
12416 
12417 	dict_add_nr_str(dict, "char", 0L, last_csearch());
12418 	dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL);
12419 	dict_add_nr_str(dict, "until", last_csearch_until(), NULL);
12420     }
12421 }
12422 
12423 /*
12424  * "getcmdline()" function
12425  */
12426     static void
12427 f_getcmdline(typval_T *argvars UNUSED, typval_T *rettv)
12428 {
12429     rettv->v_type = VAR_STRING;
12430     rettv->vval.v_string = get_cmdline_str();
12431 }
12432 
12433 /*
12434  * "getcmdpos()" function
12435  */
12436     static void
12437 f_getcmdpos(typval_T *argvars UNUSED, typval_T *rettv)
12438 {
12439     rettv->vval.v_number = get_cmdline_pos() + 1;
12440 }
12441 
12442 /*
12443  * "getcmdtype()" function
12444  */
12445     static void
12446 f_getcmdtype(typval_T *argvars UNUSED, typval_T *rettv)
12447 {
12448     rettv->v_type = VAR_STRING;
12449     rettv->vval.v_string = alloc(2);
12450     if (rettv->vval.v_string != NULL)
12451     {
12452 	rettv->vval.v_string[0] = get_cmdline_type();
12453 	rettv->vval.v_string[1] = NUL;
12454     }
12455 }
12456 
12457 /*
12458  * "getcmdwintype()" function
12459  */
12460     static void
12461 f_getcmdwintype(typval_T *argvars UNUSED, typval_T *rettv)
12462 {
12463     rettv->v_type = VAR_STRING;
12464     rettv->vval.v_string = NULL;
12465 #ifdef FEAT_CMDWIN
12466     rettv->vval.v_string = alloc(2);
12467     if (rettv->vval.v_string != NULL)
12468     {
12469 	rettv->vval.v_string[0] = cmdwin_type;
12470 	rettv->vval.v_string[1] = NUL;
12471     }
12472 #endif
12473 }
12474 
12475 /*
12476  * "getcwd()" function
12477  */
12478     static void
12479 f_getcwd(typval_T *argvars, typval_T *rettv)
12480 {
12481     win_T	*wp = NULL;
12482     char_u	*cwd;
12483 
12484     rettv->v_type = VAR_STRING;
12485     rettv->vval.v_string = NULL;
12486 
12487     wp = find_tabwin(&argvars[0], &argvars[1]);
12488     if (wp != NULL)
12489     {
12490 	if (wp->w_localdir != NULL)
12491 	    rettv->vval.v_string = vim_strsave(wp->w_localdir);
12492 	else if(globaldir != NULL)
12493 	    rettv->vval.v_string = vim_strsave(globaldir);
12494 	else
12495 	{
12496 	    cwd = alloc(MAXPATHL);
12497 	    if (cwd != NULL)
12498 	    {
12499 		if (mch_dirname(cwd, MAXPATHL) != FAIL)
12500 		    rettv->vval.v_string = vim_strsave(cwd);
12501 		vim_free(cwd);
12502 	    }
12503 	}
12504 #ifdef BACKSLASH_IN_FILENAME
12505 	if (rettv->vval.v_string != NULL)
12506 	    slash_adjust(rettv->vval.v_string);
12507 #endif
12508     }
12509 }
12510 
12511 /*
12512  * "getfontname()" function
12513  */
12514     static void
12515 f_getfontname(typval_T *argvars UNUSED, typval_T *rettv)
12516 {
12517     rettv->v_type = VAR_STRING;
12518     rettv->vval.v_string = NULL;
12519 #ifdef FEAT_GUI
12520     if (gui.in_use)
12521     {
12522 	GuiFont font;
12523 	char_u	*name = NULL;
12524 
12525 	if (argvars[0].v_type == VAR_UNKNOWN)
12526 	{
12527 	    /* Get the "Normal" font.  Either the name saved by
12528 	     * hl_set_font_name() or from the font ID. */
12529 	    font = gui.norm_font;
12530 	    name = hl_get_font_name();
12531 	}
12532 	else
12533 	{
12534 	    name = get_tv_string(&argvars[0]);
12535 	    if (STRCMP(name, "*") == 0)	    /* don't use font dialog */
12536 		return;
12537 	    font = gui_mch_get_font(name, FALSE);
12538 	    if (font == NOFONT)
12539 		return;	    /* Invalid font name, return empty string. */
12540 	}
12541 	rettv->vval.v_string = gui_mch_get_fontname(font, name);
12542 	if (argvars[0].v_type != VAR_UNKNOWN)
12543 	    gui_mch_free_font(font);
12544     }
12545 #endif
12546 }
12547 
12548 /*
12549  * "getfperm({fname})" function
12550  */
12551     static void
12552 f_getfperm(typval_T *argvars, typval_T *rettv)
12553 {
12554     char_u	*fname;
12555     struct stat st;
12556     char_u	*perm = NULL;
12557     char_u	flags[] = "rwx";
12558     int		i;
12559 
12560     fname = get_tv_string(&argvars[0]);
12561 
12562     rettv->v_type = VAR_STRING;
12563     if (mch_stat((char *)fname, &st) >= 0)
12564     {
12565 	perm = vim_strsave((char_u *)"---------");
12566 	if (perm != NULL)
12567 	{
12568 	    for (i = 0; i < 9; i++)
12569 	    {
12570 		if (st.st_mode & (1 << (8 - i)))
12571 		    perm[i] = flags[i % 3];
12572 	    }
12573 	}
12574     }
12575     rettv->vval.v_string = perm;
12576 }
12577 
12578 /*
12579  * "getfsize({fname})" function
12580  */
12581     static void
12582 f_getfsize(typval_T *argvars, typval_T *rettv)
12583 {
12584     char_u	*fname;
12585     struct stat	st;
12586 
12587     fname = get_tv_string(&argvars[0]);
12588 
12589     rettv->v_type = VAR_NUMBER;
12590 
12591     if (mch_stat((char *)fname, &st) >= 0)
12592     {
12593 	if (mch_isdir(fname))
12594 	    rettv->vval.v_number = 0;
12595 	else
12596 	{
12597 	    rettv->vval.v_number = (varnumber_T)st.st_size;
12598 
12599 	    /* non-perfect check for overflow */
12600 	    if ((off_t)rettv->vval.v_number != (off_t)st.st_size)
12601 		rettv->vval.v_number = -2;
12602 	}
12603     }
12604     else
12605 	  rettv->vval.v_number = -1;
12606 }
12607 
12608 /*
12609  * "getftime({fname})" function
12610  */
12611     static void
12612 f_getftime(typval_T *argvars, typval_T *rettv)
12613 {
12614     char_u	*fname;
12615     struct stat	st;
12616 
12617     fname = get_tv_string(&argvars[0]);
12618 
12619     if (mch_stat((char *)fname, &st) >= 0)
12620 	rettv->vval.v_number = (varnumber_T)st.st_mtime;
12621     else
12622 	rettv->vval.v_number = -1;
12623 }
12624 
12625 /*
12626  * "getftype({fname})" function
12627  */
12628     static void
12629 f_getftype(typval_T *argvars, typval_T *rettv)
12630 {
12631     char_u	*fname;
12632     struct stat st;
12633     char_u	*type = NULL;
12634     char	*t;
12635 
12636     fname = get_tv_string(&argvars[0]);
12637 
12638     rettv->v_type = VAR_STRING;
12639     if (mch_lstat((char *)fname, &st) >= 0)
12640     {
12641 #ifdef S_ISREG
12642 	if (S_ISREG(st.st_mode))
12643 	    t = "file";
12644 	else if (S_ISDIR(st.st_mode))
12645 	    t = "dir";
12646 # ifdef S_ISLNK
12647 	else if (S_ISLNK(st.st_mode))
12648 	    t = "link";
12649 # endif
12650 # ifdef S_ISBLK
12651 	else if (S_ISBLK(st.st_mode))
12652 	    t = "bdev";
12653 # endif
12654 # ifdef S_ISCHR
12655 	else if (S_ISCHR(st.st_mode))
12656 	    t = "cdev";
12657 # endif
12658 # ifdef S_ISFIFO
12659 	else if (S_ISFIFO(st.st_mode))
12660 	    t = "fifo";
12661 # endif
12662 # ifdef S_ISSOCK
12663 	else if (S_ISSOCK(st.st_mode))
12664 	    t = "fifo";
12665 # endif
12666 	else
12667 	    t = "other";
12668 #else
12669 # ifdef S_IFMT
12670 	switch (st.st_mode & S_IFMT)
12671 	{
12672 	    case S_IFREG: t = "file"; break;
12673 	    case S_IFDIR: t = "dir"; break;
12674 #  ifdef S_IFLNK
12675 	    case S_IFLNK: t = "link"; break;
12676 #  endif
12677 #  ifdef S_IFBLK
12678 	    case S_IFBLK: t = "bdev"; break;
12679 #  endif
12680 #  ifdef S_IFCHR
12681 	    case S_IFCHR: t = "cdev"; break;
12682 #  endif
12683 #  ifdef S_IFIFO
12684 	    case S_IFIFO: t = "fifo"; break;
12685 #  endif
12686 #  ifdef S_IFSOCK
12687 	    case S_IFSOCK: t = "socket"; break;
12688 #  endif
12689 	    default: t = "other";
12690 	}
12691 # else
12692 	if (mch_isdir(fname))
12693 	    t = "dir";
12694 	else
12695 	    t = "file";
12696 # endif
12697 #endif
12698 	type = vim_strsave((char_u *)t);
12699     }
12700     rettv->vval.v_string = type;
12701 }
12702 
12703 /*
12704  * "getline(lnum, [end])" function
12705  */
12706     static void
12707 f_getline(typval_T *argvars, typval_T *rettv)
12708 {
12709     linenr_T	lnum;
12710     linenr_T	end;
12711     int		retlist;
12712 
12713     lnum = get_tv_lnum(argvars);
12714     if (argvars[1].v_type == VAR_UNKNOWN)
12715     {
12716 	end = 0;
12717 	retlist = FALSE;
12718     }
12719     else
12720     {
12721 	end = get_tv_lnum(&argvars[1]);
12722 	retlist = TRUE;
12723     }
12724 
12725     get_buffer_lines(curbuf, lnum, end, retlist, rettv);
12726 }
12727 
12728 /*
12729  * "getmatches()" function
12730  */
12731     static void
12732 f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
12733 {
12734 #ifdef FEAT_SEARCH_EXTRA
12735     dict_T	*dict;
12736     matchitem_T	*cur = curwin->w_match_head;
12737     int		i;
12738 
12739     if (rettv_list_alloc(rettv) == OK)
12740     {
12741 	while (cur != NULL)
12742 	{
12743 	    dict = dict_alloc();
12744 	    if (dict == NULL)
12745 		return;
12746 	    if (cur->match.regprog == NULL)
12747 	    {
12748 		/* match added with matchaddpos() */
12749 		for (i = 0; i < MAXPOSMATCH; ++i)
12750 		{
12751 		    llpos_T	*llpos;
12752 		    char	buf[6];
12753 		    list_T	*l;
12754 
12755 		    llpos = &cur->pos.pos[i];
12756 		    if (llpos->lnum == 0)
12757 			break;
12758 		    l = list_alloc();
12759 		    if (l == NULL)
12760 			break;
12761 		    list_append_number(l, (varnumber_T)llpos->lnum);
12762 		    if (llpos->col > 0)
12763 		    {
12764 			list_append_number(l, (varnumber_T)llpos->col);
12765 			list_append_number(l, (varnumber_T)llpos->len);
12766 		    }
12767 		    sprintf(buf, "pos%d", i + 1);
12768 		    dict_add_list(dict, buf, l);
12769 		}
12770 	    }
12771 	    else
12772 	    {
12773 		dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
12774 	    }
12775 	    dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
12776 	    dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
12777 	    dict_add_nr_str(dict, "id", (long)cur->id, NULL);
12778 # ifdef FEAT_CONCEAL
12779 	    if (cur->conceal_char)
12780 	    {
12781 		char_u buf[MB_MAXBYTES + 1];
12782 
12783 		buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
12784 		dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf);
12785 	    }
12786 # endif
12787 	    list_append_dict(rettv->vval.v_list, dict);
12788 	    cur = cur->next;
12789 	}
12790     }
12791 #endif
12792 }
12793 
12794 /*
12795  * "getpid()" function
12796  */
12797     static void
12798 f_getpid(typval_T *argvars UNUSED, typval_T *rettv)
12799 {
12800     rettv->vval.v_number = mch_get_pid();
12801 }
12802 
12803 static void getpos_both(typval_T *argvars, typval_T *rettv, int getcurpos);
12804 
12805 /*
12806  * "getcurpos()" function
12807  */
12808     static void
12809 f_getcurpos(typval_T *argvars, typval_T *rettv)
12810 {
12811     getpos_both(argvars, rettv, TRUE);
12812 }
12813 
12814 /*
12815  * "getpos(string)" function
12816  */
12817     static void
12818 f_getpos(typval_T *argvars, typval_T *rettv)
12819 {
12820     getpos_both(argvars, rettv, FALSE);
12821 }
12822 
12823     static void
12824 getpos_both(
12825     typval_T	*argvars,
12826     typval_T	*rettv,
12827     int		getcurpos)
12828 {
12829     pos_T	*fp;
12830     list_T	*l;
12831     int		fnum = -1;
12832 
12833     if (rettv_list_alloc(rettv) == OK)
12834     {
12835 	l = rettv->vval.v_list;
12836 	if (getcurpos)
12837 	    fp = &curwin->w_cursor;
12838 	else
12839 	    fp = var2fpos(&argvars[0], TRUE, &fnum);
12840 	if (fnum != -1)
12841 	    list_append_number(l, (varnumber_T)fnum);
12842 	else
12843 	    list_append_number(l, (varnumber_T)0);
12844 	list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum
12845 							    : (varnumber_T)0);
12846 	list_append_number(l, (fp != NULL)
12847 		     ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
12848 							    : (varnumber_T)0);
12849 	list_append_number(l,
12850 #ifdef FEAT_VIRTUALEDIT
12851 				(fp != NULL) ? (varnumber_T)fp->coladd :
12852 #endif
12853 							      (varnumber_T)0);
12854 	if (getcurpos)
12855 	{
12856 	    update_curswant();
12857 	    list_append_number(l, curwin->w_curswant == MAXCOL ?
12858 		    (varnumber_T)MAXCOL : (varnumber_T)curwin->w_curswant + 1);
12859 	}
12860     }
12861     else
12862 	rettv->vval.v_number = FALSE;
12863 }
12864 
12865 /*
12866  * "getqflist()" and "getloclist()" functions
12867  */
12868     static void
12869 f_getqflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
12870 {
12871 #ifdef FEAT_QUICKFIX
12872     win_T	*wp;
12873 #endif
12874 
12875 #ifdef FEAT_QUICKFIX
12876     if (rettv_list_alloc(rettv) == OK)
12877     {
12878 	wp = NULL;
12879 	if (argvars[0].v_type != VAR_UNKNOWN)	/* getloclist() */
12880 	{
12881 	    wp = find_win_by_nr(&argvars[0], NULL);
12882 	    if (wp == NULL)
12883 		return;
12884 	}
12885 
12886 	(void)get_errorlist(wp, rettv->vval.v_list);
12887     }
12888 #endif
12889 }
12890 
12891 /*
12892  * "getreg()" function
12893  */
12894     static void
12895 f_getreg(typval_T *argvars, typval_T *rettv)
12896 {
12897     char_u	*strregname;
12898     int		regname;
12899     int		arg2 = FALSE;
12900     int		return_list = FALSE;
12901     int		error = FALSE;
12902 
12903     if (argvars[0].v_type != VAR_UNKNOWN)
12904     {
12905 	strregname = get_tv_string_chk(&argvars[0]);
12906 	error = strregname == NULL;
12907 	if (argvars[1].v_type != VAR_UNKNOWN)
12908 	{
12909 	    arg2 = get_tv_number_chk(&argvars[1], &error);
12910 	    if (!error && argvars[2].v_type != VAR_UNKNOWN)
12911 		return_list = get_tv_number_chk(&argvars[2], &error);
12912 	}
12913     }
12914     else
12915 	strregname = vimvars[VV_REG].vv_str;
12916 
12917     if (error)
12918 	return;
12919 
12920     regname = (strregname == NULL ? '"' : *strregname);
12921     if (regname == 0)
12922 	regname = '"';
12923 
12924     if (return_list)
12925     {
12926 	rettv->v_type = VAR_LIST;
12927 	rettv->vval.v_list = (list_T *)get_reg_contents(regname,
12928 				      (arg2 ? GREG_EXPR_SRC : 0) | GREG_LIST);
12929 	if (rettv->vval.v_list != NULL)
12930 	    ++rettv->vval.v_list->lv_refcount;
12931     }
12932     else
12933     {
12934 	rettv->v_type = VAR_STRING;
12935 	rettv->vval.v_string = get_reg_contents(regname,
12936 						    arg2 ? GREG_EXPR_SRC : 0);
12937     }
12938 }
12939 
12940 /*
12941  * "getregtype()" function
12942  */
12943     static void
12944 f_getregtype(typval_T *argvars, typval_T *rettv)
12945 {
12946     char_u	*strregname;
12947     int		regname;
12948     char_u	buf[NUMBUFLEN + 2];
12949     long	reglen = 0;
12950 
12951     if (argvars[0].v_type != VAR_UNKNOWN)
12952     {
12953 	strregname = get_tv_string_chk(&argvars[0]);
12954 	if (strregname == NULL)	    /* type error; errmsg already given */
12955 	{
12956 	    rettv->v_type = VAR_STRING;
12957 	    rettv->vval.v_string = NULL;
12958 	    return;
12959 	}
12960     }
12961     else
12962 	/* Default to v:register */
12963 	strregname = vimvars[VV_REG].vv_str;
12964 
12965     regname = (strregname == NULL ? '"' : *strregname);
12966     if (regname == 0)
12967 	regname = '"';
12968 
12969     buf[0] = NUL;
12970     buf[1] = NUL;
12971     switch (get_reg_type(regname, &reglen))
12972     {
12973 	case MLINE: buf[0] = 'V'; break;
12974 	case MCHAR: buf[0] = 'v'; break;
12975 	case MBLOCK:
12976 		buf[0] = Ctrl_V;
12977 		sprintf((char *)buf + 1, "%ld", reglen + 1);
12978 		break;
12979     }
12980     rettv->v_type = VAR_STRING;
12981     rettv->vval.v_string = vim_strsave(buf);
12982 }
12983 
12984 /*
12985  * "gettabvar()" function
12986  */
12987     static void
12988 f_gettabvar(typval_T *argvars, typval_T *rettv)
12989 {
12990     win_T	*oldcurwin;
12991     tabpage_T	*tp, *oldtabpage;
12992     dictitem_T	*v;
12993     char_u	*varname;
12994     int		done = FALSE;
12995 
12996     rettv->v_type = VAR_STRING;
12997     rettv->vval.v_string = NULL;
12998 
12999     varname = get_tv_string_chk(&argvars[1]);
13000     tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
13001     if (tp != NULL && varname != NULL)
13002     {
13003 	/* Set tp to be our tabpage, temporarily.  Also set the window to the
13004 	 * first window in the tabpage, otherwise the window is not valid. */
13005 	if (switch_win(&oldcurwin, &oldtabpage,
13006 		    tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin, tp, TRUE)
13007 									== OK)
13008 	{
13009 	    /* look up the variable */
13010 	    /* Let gettabvar({nr}, "") return the "t:" dictionary. */
13011 	    v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE);
13012 	    if (v != NULL)
13013 	    {
13014 		copy_tv(&v->di_tv, rettv);
13015 		done = TRUE;
13016 	    }
13017 	}
13018 
13019 	/* restore previous notion of curwin */
13020 	restore_win(oldcurwin, oldtabpage, TRUE);
13021     }
13022 
13023     if (!done && argvars[2].v_type != VAR_UNKNOWN)
13024 	copy_tv(&argvars[2], rettv);
13025 }
13026 
13027 /*
13028  * "gettabwinvar()" function
13029  */
13030     static void
13031 f_gettabwinvar(typval_T *argvars, typval_T *rettv)
13032 {
13033     getwinvar(argvars, rettv, 1);
13034 }
13035 
13036 /*
13037  * "getwinposx()" function
13038  */
13039     static void
13040 f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
13041 {
13042     rettv->vval.v_number = -1;
13043 #ifdef FEAT_GUI
13044     if (gui.in_use)
13045     {
13046 	int	    x, y;
13047 
13048 	if (gui_mch_get_winpos(&x, &y) == OK)
13049 	    rettv->vval.v_number = x;
13050     }
13051 #endif
13052 }
13053 
13054 /*
13055  * "win_findbuf()" function
13056  */
13057     static void
13058 f_win_findbuf(typval_T *argvars, typval_T *rettv)
13059 {
13060     if (rettv_list_alloc(rettv) != FAIL)
13061 	win_findbuf(argvars, rettv->vval.v_list);
13062 }
13063 
13064 /*
13065  * "win_getid()" function
13066  */
13067     static void
13068 f_win_getid(typval_T *argvars, typval_T *rettv)
13069 {
13070     rettv->vval.v_number = win_getid(argvars);
13071 }
13072 
13073 /*
13074  * "win_gotoid()" function
13075  */
13076     static void
13077 f_win_gotoid(typval_T *argvars, typval_T *rettv)
13078 {
13079     rettv->vval.v_number = win_gotoid(argvars);
13080 }
13081 
13082 /*
13083  * "win_id2tabwin()" function
13084  */
13085     static void
13086 f_win_id2tabwin(typval_T *argvars, typval_T *rettv)
13087 {
13088     if (rettv_list_alloc(rettv) != FAIL)
13089 	win_id2tabwin(argvars, rettv->vval.v_list);
13090 }
13091 
13092 /*
13093  * "win_id2win()" function
13094  */
13095     static void
13096 f_win_id2win(typval_T *argvars, typval_T *rettv)
13097 {
13098     rettv->vval.v_number = win_id2win(argvars);
13099 }
13100 
13101 /*
13102  * "getwinposy()" function
13103  */
13104     static void
13105 f_getwinposy(typval_T *argvars UNUSED, typval_T *rettv)
13106 {
13107     rettv->vval.v_number = -1;
13108 #ifdef FEAT_GUI
13109     if (gui.in_use)
13110     {
13111 	int	    x, y;
13112 
13113 	if (gui_mch_get_winpos(&x, &y) == OK)
13114 	    rettv->vval.v_number = y;
13115     }
13116 #endif
13117 }
13118 
13119 /*
13120  * Find window specified by "vp" in tabpage "tp".
13121  */
13122     static win_T *
13123 find_win_by_nr(
13124     typval_T	*vp,
13125     tabpage_T	*tp UNUSED)	/* NULL for current tab page */
13126 {
13127 #ifdef FEAT_WINDOWS
13128     win_T	*wp;
13129 #endif
13130     int		nr;
13131 
13132     nr = get_tv_number_chk(vp, NULL);
13133 
13134 #ifdef FEAT_WINDOWS
13135     if (nr < 0)
13136 	return NULL;
13137     if (nr == 0)
13138 	return curwin;
13139 
13140     for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin;
13141 						  wp != NULL; wp = wp->w_next)
13142 	if (--nr <= 0)
13143 	    break;
13144     return wp;
13145 #else
13146     if (nr == 0 || nr == 1)
13147 	return curwin;
13148     return NULL;
13149 #endif
13150 }
13151 
13152 /*
13153  * Find window specified by "wvp" in tabpage "tvp".
13154  */
13155     static win_T *
13156 find_tabwin(
13157     typval_T	*wvp,	/* VAR_UNKNOWN for current window */
13158     typval_T	*tvp)	/* VAR_UNKNOWN for current tab page */
13159 {
13160     win_T	*wp = NULL;
13161     tabpage_T	*tp = NULL;
13162     long	n;
13163 
13164     if (wvp->v_type != VAR_UNKNOWN)
13165     {
13166 	if (tvp->v_type != VAR_UNKNOWN)
13167 	{
13168 	    n = get_tv_number(tvp);
13169 	    if (n >= 0)
13170 		tp = find_tabpage(n);
13171 	}
13172 	else
13173 	    tp = curtab;
13174 
13175 	if (tp != NULL)
13176 	    wp = find_win_by_nr(wvp, tp);
13177     }
13178     else
13179 	wp = curwin;
13180 
13181     return wp;
13182 }
13183 
13184 /*
13185  * "getwinvar()" function
13186  */
13187     static void
13188 f_getwinvar(typval_T *argvars, typval_T *rettv)
13189 {
13190     getwinvar(argvars, rettv, 0);
13191 }
13192 
13193 /*
13194  * getwinvar() and gettabwinvar()
13195  */
13196     static void
13197 getwinvar(
13198     typval_T	*argvars,
13199     typval_T	*rettv,
13200     int		off)	    /* 1 for gettabwinvar() */
13201 {
13202     win_T	*win;
13203     char_u	*varname;
13204     dictitem_T	*v;
13205     tabpage_T	*tp = NULL;
13206     int		done = FALSE;
13207 #ifdef FEAT_WINDOWS
13208     win_T	*oldcurwin;
13209     tabpage_T	*oldtabpage;
13210     int		need_switch_win;
13211 #endif
13212 
13213 #ifdef FEAT_WINDOWS
13214     if (off == 1)
13215 	tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
13216     else
13217 	tp = curtab;
13218 #endif
13219     win = find_win_by_nr(&argvars[off], tp);
13220     varname = get_tv_string_chk(&argvars[off + 1]);
13221     ++emsg_off;
13222 
13223     rettv->v_type = VAR_STRING;
13224     rettv->vval.v_string = NULL;
13225 
13226     if (win != NULL && varname != NULL)
13227     {
13228 #ifdef FEAT_WINDOWS
13229 	/* Set curwin to be our win, temporarily.  Also set the tabpage,
13230 	 * otherwise the window is not valid. Only do this when needed,
13231 	 * autocommands get blocked. */
13232 	need_switch_win = !(tp == curtab && win == curwin);
13233 	if (!need_switch_win
13234 		  || switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK)
13235 #endif
13236 	{
13237 	    if (*varname == '&')	/* window-local-option */
13238 	    {
13239 		if (get_option_tv(&varname, rettv, 1) == OK)
13240 		    done = TRUE;
13241 	    }
13242 	    else
13243 	    {
13244 		/* Look up the variable. */
13245 		/* Let getwinvar({nr}, "") return the "w:" dictionary. */
13246 		v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w',
13247 							      varname, FALSE);
13248 		if (v != NULL)
13249 		{
13250 		    copy_tv(&v->di_tv, rettv);
13251 		    done = TRUE;
13252 		}
13253 	    }
13254 	}
13255 
13256 #ifdef FEAT_WINDOWS
13257 	if (need_switch_win)
13258 	    /* restore previous notion of curwin */
13259 	    restore_win(oldcurwin, oldtabpage, TRUE);
13260 #endif
13261     }
13262 
13263     if (!done && argvars[off + 2].v_type != VAR_UNKNOWN)
13264 	/* use the default return value */
13265 	copy_tv(&argvars[off + 2], rettv);
13266 
13267     --emsg_off;
13268 }
13269 
13270 /*
13271  * "glob()" function
13272  */
13273     static void
13274 f_glob(typval_T *argvars, typval_T *rettv)
13275 {
13276     int		options = WILD_SILENT|WILD_USE_NL;
13277     expand_T	xpc;
13278     int		error = FALSE;
13279 
13280     /* When the optional second argument is non-zero, don't remove matches
13281      * for 'wildignore' and don't put matches for 'suffixes' at the end. */
13282     rettv->v_type = VAR_STRING;
13283     if (argvars[1].v_type != VAR_UNKNOWN)
13284     {
13285 	if (get_tv_number_chk(&argvars[1], &error))
13286 	    options |= WILD_KEEP_ALL;
13287 	if (argvars[2].v_type != VAR_UNKNOWN)
13288 	{
13289 	    if (get_tv_number_chk(&argvars[2], &error))
13290 	    {
13291 		rettv->v_type = VAR_LIST;
13292 		rettv->vval.v_list = NULL;
13293 	    }
13294 	    if (argvars[3].v_type != VAR_UNKNOWN
13295 				    && get_tv_number_chk(&argvars[3], &error))
13296 		options |= WILD_ALLLINKS;
13297 	}
13298     }
13299     if (!error)
13300     {
13301 	ExpandInit(&xpc);
13302 	xpc.xp_context = EXPAND_FILES;
13303 	if (p_wic)
13304 	    options += WILD_ICASE;
13305 	if (rettv->v_type == VAR_STRING)
13306 	    rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]),
13307 						     NULL, options, WILD_ALL);
13308 	else if (rettv_list_alloc(rettv) != FAIL)
13309 	{
13310 	  int i;
13311 
13312 	  ExpandOne(&xpc, get_tv_string(&argvars[0]),
13313 						NULL, options, WILD_ALL_KEEP);
13314 	  for (i = 0; i < xpc.xp_numfiles; i++)
13315 	      list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
13316 
13317 	  ExpandCleanup(&xpc);
13318 	}
13319     }
13320     else
13321 	rettv->vval.v_string = NULL;
13322 }
13323 
13324 /*
13325  * "globpath()" function
13326  */
13327     static void
13328 f_globpath(typval_T *argvars, typval_T *rettv)
13329 {
13330     int		flags = 0;
13331     char_u	buf1[NUMBUFLEN];
13332     char_u	*file = get_tv_string_buf_chk(&argvars[1], buf1);
13333     int		error = FALSE;
13334     garray_T	ga;
13335     int		i;
13336 
13337     /* When the optional second argument is non-zero, don't remove matches
13338     * for 'wildignore' and don't put matches for 'suffixes' at the end. */
13339     rettv->v_type = VAR_STRING;
13340     if (argvars[2].v_type != VAR_UNKNOWN)
13341     {
13342 	if (get_tv_number_chk(&argvars[2], &error))
13343 	    flags |= WILD_KEEP_ALL;
13344 	if (argvars[3].v_type != VAR_UNKNOWN)
13345 	{
13346 	    if (get_tv_number_chk(&argvars[3], &error))
13347 	    {
13348 		rettv->v_type = VAR_LIST;
13349 		rettv->vval.v_list = NULL;
13350 	    }
13351 	    if (argvars[4].v_type != VAR_UNKNOWN
13352 				    && get_tv_number_chk(&argvars[4], &error))
13353 		flags |= WILD_ALLLINKS;
13354 	}
13355     }
13356     if (file != NULL && !error)
13357     {
13358 	ga_init2(&ga, (int)sizeof(char_u *), 10);
13359 	globpath(get_tv_string(&argvars[0]), file, &ga, flags);
13360 	if (rettv->v_type == VAR_STRING)
13361 	    rettv->vval.v_string = ga_concat_strings(&ga, "\n");
13362 	else if (rettv_list_alloc(rettv) != FAIL)
13363 	    for (i = 0; i < ga.ga_len; ++i)
13364 		list_append_string(rettv->vval.v_list,
13365 					    ((char_u **)(ga.ga_data))[i], -1);
13366 	ga_clear_strings(&ga);
13367     }
13368     else
13369 	rettv->vval.v_string = NULL;
13370 }
13371 
13372 /*
13373  * "glob2regpat()" function
13374  */
13375     static void
13376 f_glob2regpat(typval_T *argvars, typval_T *rettv)
13377 {
13378     char_u	*pat = get_tv_string_chk(&argvars[0]);
13379 
13380     rettv->v_type = VAR_STRING;
13381     rettv->vval.v_string = (pat == NULL)
13382 			 ? NULL : file_pat_to_reg_pat(pat, NULL, NULL, FALSE);
13383 }
13384 
13385 /*
13386  * "has()" function
13387  */
13388     static void
13389 f_has(typval_T *argvars, typval_T *rettv)
13390 {
13391     int		i;
13392     char_u	*name;
13393     int		n = FALSE;
13394     static char	*(has_list[]) =
13395     {
13396 #ifdef AMIGA
13397 	"amiga",
13398 # ifdef FEAT_ARP
13399 	"arp",
13400 # endif
13401 #endif
13402 #ifdef __BEOS__
13403 	"beos",
13404 #endif
13405 #ifdef MACOS
13406 	"mac",
13407 #endif
13408 #if defined(MACOS_X_UNIX)
13409 	"macunix",  /* built with 'darwin' enabled */
13410 #endif
13411 #if defined(__APPLE__) && __APPLE__ == 1
13412 	"osx",	    /* built with or without 'darwin' enabled */
13413 #endif
13414 #ifdef __QNX__
13415 	"qnx",
13416 #endif
13417 #ifdef UNIX
13418 	"unix",
13419 #endif
13420 #ifdef VMS
13421 	"vms",
13422 #endif
13423 #ifdef WIN32
13424 	"win32",
13425 #endif
13426 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__))
13427 	"win32unix",
13428 #endif
13429 #if defined(WIN64) || defined(_WIN64)
13430 	"win64",
13431 #endif
13432 #ifdef EBCDIC
13433 	"ebcdic",
13434 #endif
13435 #ifndef CASE_INSENSITIVE_FILENAME
13436 	"fname_case",
13437 #endif
13438 #ifdef HAVE_ACL
13439 	"acl",
13440 #endif
13441 #ifdef FEAT_ARABIC
13442 	"arabic",
13443 #endif
13444 #ifdef FEAT_AUTOCMD
13445 	"autocmd",
13446 #endif
13447 #ifdef FEAT_BEVAL
13448 	"balloon_eval",
13449 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */
13450 	"balloon_multiline",
13451 # endif
13452 #endif
13453 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
13454 	"builtin_terms",
13455 # ifdef ALL_BUILTIN_TCAPS
13456 	"all_builtin_terms",
13457 # endif
13458 #endif
13459 #if defined(FEAT_BROWSE) && (defined(USE_FILE_CHOOSER) \
13460 	|| defined(FEAT_GUI_W32) \
13461 	|| defined(FEAT_GUI_MOTIF))
13462 	"browsefilter",
13463 #endif
13464 #ifdef FEAT_BYTEOFF
13465 	"byte_offset",
13466 #endif
13467 #ifdef FEAT_JOB_CHANNEL
13468 	"channel",
13469 #endif
13470 #ifdef FEAT_CINDENT
13471 	"cindent",
13472 #endif
13473 #ifdef FEAT_CLIENTSERVER
13474 	"clientserver",
13475 #endif
13476 #ifdef FEAT_CLIPBOARD
13477 	"clipboard",
13478 #endif
13479 #ifdef FEAT_CMDL_COMPL
13480 	"cmdline_compl",
13481 #endif
13482 #ifdef FEAT_CMDHIST
13483 	"cmdline_hist",
13484 #endif
13485 #ifdef FEAT_COMMENTS
13486 	"comments",
13487 #endif
13488 #ifdef FEAT_CONCEAL
13489 	"conceal",
13490 #endif
13491 #ifdef FEAT_CRYPT
13492 	"cryptv",
13493 	"crypt-blowfish",
13494 	"crypt-blowfish2",
13495 #endif
13496 #ifdef FEAT_CSCOPE
13497 	"cscope",
13498 #endif
13499 #ifdef FEAT_CURSORBIND
13500 	"cursorbind",
13501 #endif
13502 #ifdef CURSOR_SHAPE
13503 	"cursorshape",
13504 #endif
13505 #ifdef DEBUG
13506 	"debug",
13507 #endif
13508 #ifdef FEAT_CON_DIALOG
13509 	"dialog_con",
13510 #endif
13511 #ifdef FEAT_GUI_DIALOG
13512 	"dialog_gui",
13513 #endif
13514 #ifdef FEAT_DIFF
13515 	"diff",
13516 #endif
13517 #ifdef FEAT_DIGRAPHS
13518 	"digraphs",
13519 #endif
13520 #ifdef FEAT_DIRECTX
13521 	"directx",
13522 #endif
13523 #ifdef FEAT_DND
13524 	"dnd",
13525 #endif
13526 #ifdef FEAT_EMACS_TAGS
13527 	"emacs_tags",
13528 #endif
13529 	"eval",	    /* always present, of course! */
13530 	"ex_extra", /* graduated feature */
13531 #ifdef FEAT_SEARCH_EXTRA
13532 	"extra_search",
13533 #endif
13534 #ifdef FEAT_FKMAP
13535 	"farsi",
13536 #endif
13537 #ifdef FEAT_SEARCHPATH
13538 	"file_in_path",
13539 #endif
13540 #ifdef FEAT_FILTERPIPE
13541 	"filterpipe",
13542 #endif
13543 #ifdef FEAT_FIND_ID
13544 	"find_in_path",
13545 #endif
13546 #ifdef FEAT_FLOAT
13547 	"float",
13548 #endif
13549 #ifdef FEAT_FOLDING
13550 	"folding",
13551 #endif
13552 #ifdef FEAT_FOOTER
13553 	"footer",
13554 #endif
13555 #if !defined(USE_SYSTEM) && defined(UNIX)
13556 	"fork",
13557 #endif
13558 #ifdef FEAT_GETTEXT
13559 	"gettext",
13560 #endif
13561 #ifdef FEAT_GUI
13562 	"gui",
13563 #endif
13564 #ifdef FEAT_GUI_ATHENA
13565 # ifdef FEAT_GUI_NEXTAW
13566 	"gui_neXtaw",
13567 # else
13568 	"gui_athena",
13569 # endif
13570 #endif
13571 #ifdef FEAT_GUI_GTK
13572 	"gui_gtk",
13573 # ifdef USE_GTK3
13574 	"gui_gtk3",
13575 # else
13576 	"gui_gtk2",
13577 # endif
13578 #endif
13579 #ifdef FEAT_GUI_GNOME
13580 	"gui_gnome",
13581 #endif
13582 #ifdef FEAT_GUI_MAC
13583 	"gui_mac",
13584 #endif
13585 #ifdef FEAT_GUI_MOTIF
13586 	"gui_motif",
13587 #endif
13588 #ifdef FEAT_GUI_PHOTON
13589 	"gui_photon",
13590 #endif
13591 #ifdef FEAT_GUI_W32
13592 	"gui_win32",
13593 #endif
13594 #ifdef FEAT_HANGULIN
13595 	"hangul_input",
13596 #endif
13597 #if defined(HAVE_ICONV_H) && defined(USE_ICONV)
13598 	"iconv",
13599 #endif
13600 #ifdef FEAT_INS_EXPAND
13601 	"insert_expand",
13602 #endif
13603 #ifdef FEAT_JOB_CHANNEL
13604 	"job",
13605 #endif
13606 #ifdef FEAT_JUMPLIST
13607 	"jumplist",
13608 #endif
13609 #ifdef FEAT_KEYMAP
13610 	"keymap",
13611 #endif
13612 #ifdef FEAT_LANGMAP
13613 	"langmap",
13614 #endif
13615 #ifdef FEAT_LIBCALL
13616 	"libcall",
13617 #endif
13618 #ifdef FEAT_LINEBREAK
13619 	"linebreak",
13620 #endif
13621 #ifdef FEAT_LISP
13622 	"lispindent",
13623 #endif
13624 #ifdef FEAT_LISTCMDS
13625 	"listcmds",
13626 #endif
13627 #ifdef FEAT_LOCALMAP
13628 	"localmap",
13629 #endif
13630 #ifdef FEAT_LUA
13631 # ifndef DYNAMIC_LUA
13632 	"lua",
13633 # endif
13634 #endif
13635 #ifdef FEAT_MENU
13636 	"menu",
13637 #endif
13638 #ifdef FEAT_SESSION
13639 	"mksession",
13640 #endif
13641 #ifdef FEAT_MODIFY_FNAME
13642 	"modify_fname",
13643 #endif
13644 #ifdef FEAT_MOUSE
13645 	"mouse",
13646 #endif
13647 #ifdef FEAT_MOUSESHAPE
13648 	"mouseshape",
13649 #endif
13650 #if defined(UNIX) || defined(VMS)
13651 # ifdef FEAT_MOUSE_DEC
13652 	"mouse_dec",
13653 # endif
13654 # ifdef FEAT_MOUSE_GPM
13655 	"mouse_gpm",
13656 # endif
13657 # ifdef FEAT_MOUSE_JSB
13658 	"mouse_jsbterm",
13659 # endif
13660 # ifdef FEAT_MOUSE_NET
13661 	"mouse_netterm",
13662 # endif
13663 # ifdef FEAT_MOUSE_PTERM
13664 	"mouse_pterm",
13665 # endif
13666 # ifdef FEAT_MOUSE_SGR
13667 	"mouse_sgr",
13668 # endif
13669 # ifdef FEAT_SYSMOUSE
13670 	"mouse_sysmouse",
13671 # endif
13672 # ifdef FEAT_MOUSE_URXVT
13673 	"mouse_urxvt",
13674 # endif
13675 # ifdef FEAT_MOUSE_XTERM
13676 	"mouse_xterm",
13677 # endif
13678 #endif
13679 #ifdef FEAT_MBYTE
13680 	"multi_byte",
13681 #endif
13682 #ifdef FEAT_MBYTE_IME
13683 	"multi_byte_ime",
13684 #endif
13685 #ifdef FEAT_MULTI_LANG
13686 	"multi_lang",
13687 #endif
13688 #ifdef FEAT_MZSCHEME
13689 #ifndef DYNAMIC_MZSCHEME
13690 	"mzscheme",
13691 #endif
13692 #endif
13693 #ifdef FEAT_OLE
13694 	"ole",
13695 #endif
13696 	"packages",
13697 #ifdef FEAT_PATH_EXTRA
13698 	"path_extra",
13699 #endif
13700 #ifdef FEAT_PERL
13701 #ifndef DYNAMIC_PERL
13702 	"perl",
13703 #endif
13704 #endif
13705 #ifdef FEAT_PERSISTENT_UNDO
13706 	"persistent_undo",
13707 #endif
13708 #ifdef FEAT_PYTHON
13709 #ifndef DYNAMIC_PYTHON
13710 	"python",
13711 #endif
13712 #endif
13713 #ifdef FEAT_PYTHON3
13714 #ifndef DYNAMIC_PYTHON3
13715 	"python3",
13716 #endif
13717 #endif
13718 #ifdef FEAT_POSTSCRIPT
13719 	"postscript",
13720 #endif
13721 #ifdef FEAT_PRINTER
13722 	"printer",
13723 #endif
13724 #ifdef FEAT_PROFILE
13725 	"profile",
13726 #endif
13727 #ifdef FEAT_RELTIME
13728 	"reltime",
13729 #endif
13730 #ifdef FEAT_QUICKFIX
13731 	"quickfix",
13732 #endif
13733 #ifdef FEAT_RIGHTLEFT
13734 	"rightleft",
13735 #endif
13736 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY)
13737 	"ruby",
13738 #endif
13739 #ifdef FEAT_SCROLLBIND
13740 	"scrollbind",
13741 #endif
13742 #ifdef FEAT_CMDL_INFO
13743 	"showcmd",
13744 	"cmdline_info",
13745 #endif
13746 #ifdef FEAT_SIGNS
13747 	"signs",
13748 #endif
13749 #ifdef FEAT_SMARTINDENT
13750 	"smartindent",
13751 #endif
13752 #ifdef STARTUPTIME
13753 	"startuptime",
13754 #endif
13755 #ifdef FEAT_STL_OPT
13756 	"statusline",
13757 #endif
13758 #ifdef FEAT_SUN_WORKSHOP
13759 	"sun_workshop",
13760 #endif
13761 #ifdef FEAT_NETBEANS_INTG
13762 	"netbeans_intg",
13763 #endif
13764 #ifdef FEAT_SPELL
13765 	"spell",
13766 #endif
13767 #ifdef FEAT_SYN_HL
13768 	"syntax",
13769 #endif
13770 #if defined(USE_SYSTEM) || !defined(UNIX)
13771 	"system",
13772 #endif
13773 #ifdef FEAT_TAG_BINS
13774 	"tag_binary",
13775 #endif
13776 #ifdef FEAT_TAG_OLDSTATIC
13777 	"tag_old_static",
13778 #endif
13779 #ifdef FEAT_TAG_ANYWHITE
13780 	"tag_any_white",
13781 #endif
13782 #ifdef FEAT_TCL
13783 # ifndef DYNAMIC_TCL
13784 	"tcl",
13785 # endif
13786 #endif
13787 #ifdef TERMINFO
13788 	"terminfo",
13789 #endif
13790 #ifdef FEAT_TERMRESPONSE
13791 	"termresponse",
13792 #endif
13793 #ifdef FEAT_TEXTOBJ
13794 	"textobjects",
13795 #endif
13796 #ifdef HAVE_TGETENT
13797 	"tgetent",
13798 #endif
13799 #ifdef FEAT_TIMERS
13800 	"timers",
13801 #endif
13802 #ifdef FEAT_TITLE
13803 	"title",
13804 #endif
13805 #ifdef FEAT_TOOLBAR
13806 	"toolbar",
13807 #endif
13808 #if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
13809 	"unnamedplus",
13810 #endif
13811 #ifdef FEAT_USR_CMDS
13812 	"user-commands",    /* was accidentally included in 5.4 */
13813 	"user_commands",
13814 #endif
13815 #ifdef FEAT_VIMINFO
13816 	"viminfo",
13817 #endif
13818 #ifdef FEAT_WINDOWS
13819 	"vertsplit",
13820 #endif
13821 #ifdef FEAT_VIRTUALEDIT
13822 	"virtualedit",
13823 #endif
13824 	"visual",
13825 #ifdef FEAT_VISUALEXTRA
13826 	"visualextra",
13827 #endif
13828 #ifdef FEAT_VREPLACE
13829 	"vreplace",
13830 #endif
13831 #ifdef FEAT_WILDIGN
13832 	"wildignore",
13833 #endif
13834 #ifdef FEAT_WILDMENU
13835 	"wildmenu",
13836 #endif
13837 #ifdef FEAT_WINDOWS
13838 	"windows",
13839 #endif
13840 #ifdef FEAT_WAK
13841 	"winaltkeys",
13842 #endif
13843 #ifdef FEAT_WRITEBACKUP
13844 	"writebackup",
13845 #endif
13846 #ifdef FEAT_XIM
13847 	"xim",
13848 #endif
13849 #ifdef FEAT_XFONTSET
13850 	"xfontset",
13851 #endif
13852 #ifdef FEAT_XPM_W32
13853 	"xpm",
13854 	"xpm_w32",	/* for backward compatibility */
13855 #else
13856 # if defined(HAVE_XPM)
13857 	"xpm",
13858 # endif
13859 #endif
13860 #ifdef USE_XSMP
13861 	"xsmp",
13862 #endif
13863 #ifdef USE_XSMP_INTERACT
13864 	"xsmp_interact",
13865 #endif
13866 #ifdef FEAT_XCLIPBOARD
13867 	"xterm_clipboard",
13868 #endif
13869 #ifdef FEAT_XTERM_SAVE
13870 	"xterm_save",
13871 #endif
13872 #if defined(UNIX) && defined(FEAT_X11)
13873 	"X11",
13874 #endif
13875 	NULL
13876     };
13877 
13878     name = get_tv_string(&argvars[0]);
13879     for (i = 0; has_list[i] != NULL; ++i)
13880 	if (STRICMP(name, has_list[i]) == 0)
13881 	{
13882 	    n = TRUE;
13883 	    break;
13884 	}
13885 
13886     if (n == FALSE)
13887     {
13888 	if (STRNICMP(name, "patch", 5) == 0)
13889 	{
13890 	    if (name[5] == '-'
13891 		    && STRLEN(name) >= 11
13892 		    && vim_isdigit(name[6])
13893 		    && vim_isdigit(name[8])
13894 		    && vim_isdigit(name[10]))
13895 	    {
13896 		int major = atoi((char *)name + 6);
13897 		int minor = atoi((char *)name + 8);
13898 
13899 		/* Expect "patch-9.9.01234". */
13900 		n = (major < VIM_VERSION_MAJOR
13901 		     || (major == VIM_VERSION_MAJOR
13902 			 && (minor < VIM_VERSION_MINOR
13903 			     || (minor == VIM_VERSION_MINOR
13904 				 && has_patch(atoi((char *)name + 10))))));
13905 	    }
13906 	    else
13907 		n = has_patch(atoi((char *)name + 5));
13908 	}
13909 	else if (STRICMP(name, "vim_starting") == 0)
13910 	    n = (starting != 0);
13911 #ifdef FEAT_MBYTE
13912 	else if (STRICMP(name, "multi_byte_encoding") == 0)
13913 	    n = has_mbyte;
13914 #endif
13915 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32)
13916 	else if (STRICMP(name, "balloon_multiline") == 0)
13917 	    n = multiline_balloon_available();
13918 #endif
13919 #ifdef DYNAMIC_TCL
13920 	else if (STRICMP(name, "tcl") == 0)
13921 	    n = tcl_enabled(FALSE);
13922 #endif
13923 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
13924 	else if (STRICMP(name, "iconv") == 0)
13925 	    n = iconv_enabled(FALSE);
13926 #endif
13927 #ifdef DYNAMIC_LUA
13928 	else if (STRICMP(name, "lua") == 0)
13929 	    n = lua_enabled(FALSE);
13930 #endif
13931 #ifdef DYNAMIC_MZSCHEME
13932 	else if (STRICMP(name, "mzscheme") == 0)
13933 	    n = mzscheme_enabled(FALSE);
13934 #endif
13935 #ifdef DYNAMIC_RUBY
13936 	else if (STRICMP(name, "ruby") == 0)
13937 	    n = ruby_enabled(FALSE);
13938 #endif
13939 #ifdef FEAT_PYTHON
13940 #ifdef DYNAMIC_PYTHON
13941 	else if (STRICMP(name, "python") == 0)
13942 	    n = python_enabled(FALSE);
13943 #endif
13944 #endif
13945 #ifdef FEAT_PYTHON3
13946 #ifdef DYNAMIC_PYTHON3
13947 	else if (STRICMP(name, "python3") == 0)
13948 	    n = python3_enabled(FALSE);
13949 #endif
13950 #endif
13951 #ifdef DYNAMIC_PERL
13952 	else if (STRICMP(name, "perl") == 0)
13953 	    n = perl_enabled(FALSE);
13954 #endif
13955 #ifdef FEAT_GUI
13956 	else if (STRICMP(name, "gui_running") == 0)
13957 	    n = (gui.in_use || gui.starting);
13958 # ifdef FEAT_GUI_W32
13959 	else if (STRICMP(name, "gui_win32s") == 0)
13960 	    n = gui_is_win32s();
13961 # endif
13962 # ifdef FEAT_BROWSE
13963 	else if (STRICMP(name, "browse") == 0)
13964 	    n = gui.in_use;	/* gui_mch_browse() works when GUI is running */
13965 # endif
13966 #endif
13967 #ifdef FEAT_SYN_HL
13968 	else if (STRICMP(name, "syntax_items") == 0)
13969 	    n = syntax_present(curwin);
13970 #endif
13971 #if defined(WIN3264)
13972 	else if (STRICMP(name, "win95") == 0)
13973 	    n = mch_windows95();
13974 #endif
13975 #ifdef FEAT_NETBEANS_INTG
13976 	else if (STRICMP(name, "netbeans_enabled") == 0)
13977 	    n = netbeans_active();
13978 #endif
13979     }
13980 
13981     rettv->vval.v_number = n;
13982 }
13983 
13984 /*
13985  * "has_key()" function
13986  */
13987     static void
13988 f_has_key(typval_T *argvars, typval_T *rettv)
13989 {
13990     if (argvars[0].v_type != VAR_DICT)
13991     {
13992 	EMSG(_(e_dictreq));
13993 	return;
13994     }
13995     if (argvars[0].vval.v_dict == NULL)
13996 	return;
13997 
13998     rettv->vval.v_number = dict_find(argvars[0].vval.v_dict,
13999 				      get_tv_string(&argvars[1]), -1) != NULL;
14000 }
14001 
14002 /*
14003  * "haslocaldir()" function
14004  */
14005     static void
14006 f_haslocaldir(typval_T *argvars, typval_T *rettv)
14007 {
14008     win_T	*wp = NULL;
14009 
14010     wp = find_tabwin(&argvars[0], &argvars[1]);
14011     rettv->vval.v_number = (wp != NULL && wp->w_localdir != NULL);
14012 }
14013 
14014 /*
14015  * "hasmapto()" function
14016  */
14017     static void
14018 f_hasmapto(typval_T *argvars, typval_T *rettv)
14019 {
14020     char_u	*name;
14021     char_u	*mode;
14022     char_u	buf[NUMBUFLEN];
14023     int		abbr = FALSE;
14024 
14025     name = get_tv_string(&argvars[0]);
14026     if (argvars[1].v_type == VAR_UNKNOWN)
14027 	mode = (char_u *)"nvo";
14028     else
14029     {
14030 	mode = get_tv_string_buf(&argvars[1], buf);
14031 	if (argvars[2].v_type != VAR_UNKNOWN)
14032 	    abbr = get_tv_number(&argvars[2]);
14033     }
14034 
14035     if (map_to_exists(name, mode, abbr))
14036 	rettv->vval.v_number = TRUE;
14037     else
14038 	rettv->vval.v_number = FALSE;
14039 }
14040 
14041 /*
14042  * "histadd()" function
14043  */
14044     static void
14045 f_histadd(typval_T *argvars UNUSED, typval_T *rettv)
14046 {
14047 #ifdef FEAT_CMDHIST
14048     int		histype;
14049     char_u	*str;
14050     char_u	buf[NUMBUFLEN];
14051 #endif
14052 
14053     rettv->vval.v_number = FALSE;
14054     if (check_restricted() || check_secure())
14055 	return;
14056 #ifdef FEAT_CMDHIST
14057     str = get_tv_string_chk(&argvars[0]);	/* NULL on type error */
14058     histype = str != NULL ? get_histtype(str) : -1;
14059     if (histype >= 0)
14060     {
14061 	str = get_tv_string_buf(&argvars[1], buf);
14062 	if (*str != NUL)
14063 	{
14064 	    init_history();
14065 	    add_to_history(histype, str, FALSE, NUL);
14066 	    rettv->vval.v_number = TRUE;
14067 	    return;
14068 	}
14069     }
14070 #endif
14071 }
14072 
14073 /*
14074  * "histdel()" function
14075  */
14076     static void
14077 f_histdel(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
14078 {
14079 #ifdef FEAT_CMDHIST
14080     int		n;
14081     char_u	buf[NUMBUFLEN];
14082     char_u	*str;
14083 
14084     str = get_tv_string_chk(&argvars[0]);	/* NULL on type error */
14085     if (str == NULL)
14086 	n = 0;
14087     else if (argvars[1].v_type == VAR_UNKNOWN)
14088 	/* only one argument: clear entire history */
14089 	n = clr_history(get_histtype(str));
14090     else if (argvars[1].v_type == VAR_NUMBER)
14091 	/* index given: remove that entry */
14092 	n = del_history_idx(get_histtype(str),
14093 					  (int)get_tv_number(&argvars[1]));
14094     else
14095 	/* string given: remove all matching entries */
14096 	n = del_history_entry(get_histtype(str),
14097 				      get_tv_string_buf(&argvars[1], buf));
14098     rettv->vval.v_number = n;
14099 #endif
14100 }
14101 
14102 /*
14103  * "histget()" function
14104  */
14105     static void
14106 f_histget(typval_T *argvars UNUSED, typval_T *rettv)
14107 {
14108 #ifdef FEAT_CMDHIST
14109     int		type;
14110     int		idx;
14111     char_u	*str;
14112 
14113     str = get_tv_string_chk(&argvars[0]);	/* NULL on type error */
14114     if (str == NULL)
14115 	rettv->vval.v_string = NULL;
14116     else
14117     {
14118 	type = get_histtype(str);
14119 	if (argvars[1].v_type == VAR_UNKNOWN)
14120 	    idx = get_history_idx(type);
14121 	else
14122 	    idx = (int)get_tv_number_chk(&argvars[1], NULL);
14123 						    /* -1 on type error */
14124 	rettv->vval.v_string = vim_strsave(get_history_entry(type, idx));
14125     }
14126 #else
14127     rettv->vval.v_string = NULL;
14128 #endif
14129     rettv->v_type = VAR_STRING;
14130 }
14131 
14132 /*
14133  * "histnr()" function
14134  */
14135     static void
14136 f_histnr(typval_T *argvars UNUSED, typval_T *rettv)
14137 {
14138     int		i;
14139 
14140 #ifdef FEAT_CMDHIST
14141     char_u	*history = get_tv_string_chk(&argvars[0]);
14142 
14143     i = history == NULL ? HIST_CMD - 1 : get_histtype(history);
14144     if (i >= HIST_CMD && i < HIST_COUNT)
14145 	i = get_history_idx(i);
14146     else
14147 #endif
14148 	i = -1;
14149     rettv->vval.v_number = i;
14150 }
14151 
14152 /*
14153  * "highlightID(name)" function
14154  */
14155     static void
14156 f_hlID(typval_T *argvars, typval_T *rettv)
14157 {
14158     rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0]));
14159 }
14160 
14161 /*
14162  * "highlight_exists()" function
14163  */
14164     static void
14165 f_hlexists(typval_T *argvars, typval_T *rettv)
14166 {
14167     rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0]));
14168 }
14169 
14170 /*
14171  * "hostname()" function
14172  */
14173     static void
14174 f_hostname(typval_T *argvars UNUSED, typval_T *rettv)
14175 {
14176     char_u hostname[256];
14177 
14178     mch_get_host_name(hostname, 256);
14179     rettv->v_type = VAR_STRING;
14180     rettv->vval.v_string = vim_strsave(hostname);
14181 }
14182 
14183 /*
14184  * iconv() function
14185  */
14186     static void
14187 f_iconv(typval_T *argvars UNUSED, typval_T *rettv)
14188 {
14189 #ifdef FEAT_MBYTE
14190     char_u	buf1[NUMBUFLEN];
14191     char_u	buf2[NUMBUFLEN];
14192     char_u	*from, *to, *str;
14193     vimconv_T	vimconv;
14194 #endif
14195 
14196     rettv->v_type = VAR_STRING;
14197     rettv->vval.v_string = NULL;
14198 
14199 #ifdef FEAT_MBYTE
14200     str = get_tv_string(&argvars[0]);
14201     from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1)));
14202     to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2)));
14203     vimconv.vc_type = CONV_NONE;
14204     convert_setup(&vimconv, from, to);
14205 
14206     /* If the encodings are equal, no conversion needed. */
14207     if (vimconv.vc_type == CONV_NONE)
14208 	rettv->vval.v_string = vim_strsave(str);
14209     else
14210 	rettv->vval.v_string = string_convert(&vimconv, str, NULL);
14211 
14212     convert_setup(&vimconv, NULL, NULL);
14213     vim_free(from);
14214     vim_free(to);
14215 #endif
14216 }
14217 
14218 /*
14219  * "indent()" function
14220  */
14221     static void
14222 f_indent(typval_T *argvars, typval_T *rettv)
14223 {
14224     linenr_T	lnum;
14225 
14226     lnum = get_tv_lnum(argvars);
14227     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
14228 	rettv->vval.v_number = get_indent_lnum(lnum);
14229     else
14230 	rettv->vval.v_number = -1;
14231 }
14232 
14233 /*
14234  * "index()" function
14235  */
14236     static void
14237 f_index(typval_T *argvars, typval_T *rettv)
14238 {
14239     list_T	*l;
14240     listitem_T	*item;
14241     long	idx = 0;
14242     int		ic = FALSE;
14243 
14244     rettv->vval.v_number = -1;
14245     if (argvars[0].v_type != VAR_LIST)
14246     {
14247 	EMSG(_(e_listreq));
14248 	return;
14249     }
14250     l = argvars[0].vval.v_list;
14251     if (l != NULL)
14252     {
14253 	item = l->lv_first;
14254 	if (argvars[2].v_type != VAR_UNKNOWN)
14255 	{
14256 	    int		error = FALSE;
14257 
14258 	    /* Start at specified item.  Use the cached index that list_find()
14259 	     * sets, so that a negative number also works. */
14260 	    item = list_find(l, get_tv_number_chk(&argvars[2], &error));
14261 	    idx = l->lv_idx;
14262 	    if (argvars[3].v_type != VAR_UNKNOWN)
14263 		ic = get_tv_number_chk(&argvars[3], &error);
14264 	    if (error)
14265 		item = NULL;
14266 	}
14267 
14268 	for ( ; item != NULL; item = item->li_next, ++idx)
14269 	    if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE))
14270 	    {
14271 		rettv->vval.v_number = idx;
14272 		break;
14273 	    }
14274     }
14275 }
14276 
14277 static int inputsecret_flag = 0;
14278 
14279 static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog);
14280 
14281 /*
14282  * This function is used by f_input() and f_inputdialog() functions. The third
14283  * argument to f_input() specifies the type of completion to use at the
14284  * prompt. The third argument to f_inputdialog() specifies the value to return
14285  * when the user cancels the prompt.
14286  */
14287     static void
14288 get_user_input(
14289     typval_T	*argvars,
14290     typval_T	*rettv,
14291     int		inputdialog)
14292 {
14293     char_u	*prompt = get_tv_string_chk(&argvars[0]);
14294     char_u	*p = NULL;
14295     int		c;
14296     char_u	buf[NUMBUFLEN];
14297     int		cmd_silent_save = cmd_silent;
14298     char_u	*defstr = (char_u *)"";
14299     int		xp_type = EXPAND_NOTHING;
14300     char_u	*xp_arg = NULL;
14301 
14302     rettv->v_type = VAR_STRING;
14303     rettv->vval.v_string = NULL;
14304 
14305 #ifdef NO_CONSOLE_INPUT
14306     /* While starting up, there is no place to enter text. */
14307     if (no_console_input())
14308 	return;
14309 #endif
14310 
14311     cmd_silent = FALSE;		/* Want to see the prompt. */
14312     if (prompt != NULL)
14313     {
14314 	/* Only the part of the message after the last NL is considered as
14315 	 * prompt for the command line */
14316 	p = vim_strrchr(prompt, '\n');
14317 	if (p == NULL)
14318 	    p = prompt;
14319 	else
14320 	{
14321 	    ++p;
14322 	    c = *p;
14323 	    *p = NUL;
14324 	    msg_start();
14325 	    msg_clr_eos();
14326 	    msg_puts_attr(prompt, echo_attr);
14327 	    msg_didout = FALSE;
14328 	    msg_starthere();
14329 	    *p = c;
14330 	}
14331 	cmdline_row = msg_row;
14332 
14333 	if (argvars[1].v_type != VAR_UNKNOWN)
14334 	{
14335 	    defstr = get_tv_string_buf_chk(&argvars[1], buf);
14336 	    if (defstr != NULL)
14337 		stuffReadbuffSpec(defstr);
14338 
14339 	    if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN)
14340 	    {
14341 		char_u	*xp_name;
14342 		int	xp_namelen;
14343 		long	argt;
14344 
14345 		/* input() with a third argument: completion */
14346 		rettv->vval.v_string = NULL;
14347 
14348 		xp_name = get_tv_string_buf_chk(&argvars[2], buf);
14349 		if (xp_name == NULL)
14350 		    return;
14351 
14352 		xp_namelen = (int)STRLEN(xp_name);
14353 
14354 		if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
14355 							     &xp_arg) == FAIL)
14356 		    return;
14357 	    }
14358 	}
14359 
14360 	if (defstr != NULL)
14361 	{
14362 	    int save_ex_normal_busy = ex_normal_busy;
14363 	    ex_normal_busy = 0;
14364 	    rettv->vval.v_string =
14365 		getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr,
14366 				  xp_type, xp_arg);
14367 	    ex_normal_busy = save_ex_normal_busy;
14368 	}
14369 	if (inputdialog && rettv->vval.v_string == NULL
14370 		&& argvars[1].v_type != VAR_UNKNOWN
14371 		&& argvars[2].v_type != VAR_UNKNOWN)
14372 	    rettv->vval.v_string = vim_strsave(get_tv_string_buf(
14373 							   &argvars[2], buf));
14374 
14375 	vim_free(xp_arg);
14376 
14377 	/* since the user typed this, no need to wait for return */
14378 	need_wait_return = FALSE;
14379 	msg_didout = FALSE;
14380     }
14381     cmd_silent = cmd_silent_save;
14382 }
14383 
14384 /*
14385  * "input()" function
14386  *     Also handles inputsecret() when inputsecret is set.
14387  */
14388     static void
14389 f_input(typval_T *argvars, typval_T *rettv)
14390 {
14391     get_user_input(argvars, rettv, FALSE);
14392 }
14393 
14394 /*
14395  * "inputdialog()" function
14396  */
14397     static void
14398 f_inputdialog(typval_T *argvars, typval_T *rettv)
14399 {
14400 #if defined(FEAT_GUI_TEXTDIALOG)
14401     /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */
14402     if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL)
14403     {
14404 	char_u	*message;
14405 	char_u	buf[NUMBUFLEN];
14406 	char_u	*defstr = (char_u *)"";
14407 
14408 	message = get_tv_string_chk(&argvars[0]);
14409 	if (argvars[1].v_type != VAR_UNKNOWN
14410 		&& (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL)
14411 	    vim_strncpy(IObuff, defstr, IOSIZE - 1);
14412 	else
14413 	    IObuff[0] = NUL;
14414 	if (message != NULL && defstr != NULL
14415 		&& do_dialog(VIM_QUESTION, NULL, message,
14416 			  (char_u *)_("&OK\n&Cancel"), 1, IObuff, FALSE) == 1)
14417 	    rettv->vval.v_string = vim_strsave(IObuff);
14418 	else
14419 	{
14420 	    if (message != NULL && defstr != NULL
14421 					&& argvars[1].v_type != VAR_UNKNOWN
14422 					&& argvars[2].v_type != VAR_UNKNOWN)
14423 		rettv->vval.v_string = vim_strsave(
14424 				      get_tv_string_buf(&argvars[2], buf));
14425 	    else
14426 		rettv->vval.v_string = NULL;
14427 	}
14428 	rettv->v_type = VAR_STRING;
14429     }
14430     else
14431 #endif
14432 	get_user_input(argvars, rettv, TRUE);
14433 }
14434 
14435 /*
14436  * "inputlist()" function
14437  */
14438     static void
14439 f_inputlist(typval_T *argvars, typval_T *rettv)
14440 {
14441     listitem_T	*li;
14442     int		selected;
14443     int		mouse_used;
14444 
14445 #ifdef NO_CONSOLE_INPUT
14446     /* While starting up, there is no place to enter text. */
14447     if (no_console_input())
14448 	return;
14449 #endif
14450     if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL)
14451     {
14452 	EMSG2(_(e_listarg), "inputlist()");
14453 	return;
14454     }
14455 
14456     msg_start();
14457     msg_row = Rows - 1;	/* for when 'cmdheight' > 1 */
14458     lines_left = Rows;	/* avoid more prompt */
14459     msg_scroll = TRUE;
14460     msg_clr_eos();
14461 
14462     for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next)
14463     {
14464 	msg_puts(get_tv_string(&li->li_tv));
14465 	msg_putchar('\n');
14466     }
14467 
14468     /* Ask for choice. */
14469     selected = prompt_for_number(&mouse_used);
14470     if (mouse_used)
14471 	selected -= lines_left;
14472 
14473     rettv->vval.v_number = selected;
14474 }
14475 
14476 
14477 static garray_T	    ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL};
14478 
14479 /*
14480  * "inputrestore()" function
14481  */
14482     static void
14483 f_inputrestore(typval_T *argvars UNUSED, typval_T *rettv)
14484 {
14485     if (ga_userinput.ga_len > 0)
14486     {
14487 	--ga_userinput.ga_len;
14488 	restore_typeahead((tasave_T *)(ga_userinput.ga_data)
14489 						       + ga_userinput.ga_len);
14490 	/* default return is zero == OK */
14491     }
14492     else if (p_verbose > 1)
14493     {
14494 	verb_msg((char_u *)_("called inputrestore() more often than inputsave()"));
14495 	rettv->vval.v_number = 1; /* Failed */
14496     }
14497 }
14498 
14499 /*
14500  * "inputsave()" function
14501  */
14502     static void
14503 f_inputsave(typval_T *argvars UNUSED, typval_T *rettv)
14504 {
14505     /* Add an entry to the stack of typeahead storage. */
14506     if (ga_grow(&ga_userinput, 1) == OK)
14507     {
14508 	save_typeahead((tasave_T *)(ga_userinput.ga_data)
14509 						       + ga_userinput.ga_len);
14510 	++ga_userinput.ga_len;
14511 	/* default return is zero == OK */
14512     }
14513     else
14514 	rettv->vval.v_number = 1; /* Failed */
14515 }
14516 
14517 /*
14518  * "inputsecret()" function
14519  */
14520     static void
14521 f_inputsecret(typval_T *argvars, typval_T *rettv)
14522 {
14523     ++cmdline_star;
14524     ++inputsecret_flag;
14525     f_input(argvars, rettv);
14526     --cmdline_star;
14527     --inputsecret_flag;
14528 }
14529 
14530 /*
14531  * "insert()" function
14532  */
14533     static void
14534 f_insert(typval_T *argvars, typval_T *rettv)
14535 {
14536     long	before = 0;
14537     listitem_T	*item;
14538     list_T	*l;
14539     int		error = FALSE;
14540 
14541     if (argvars[0].v_type != VAR_LIST)
14542 	EMSG2(_(e_listarg), "insert()");
14543     else if ((l = argvars[0].vval.v_list) != NULL
14544 	    && !tv_check_lock(l->lv_lock, (char_u *)N_("insert() argument"), TRUE))
14545     {
14546 	if (argvars[2].v_type != VAR_UNKNOWN)
14547 	    before = get_tv_number_chk(&argvars[2], &error);
14548 	if (error)
14549 	    return;		/* type error; errmsg already given */
14550 
14551 	if (before == l->lv_len)
14552 	    item = NULL;
14553 	else
14554 	{
14555 	    item = list_find(l, before);
14556 	    if (item == NULL)
14557 	    {
14558 		EMSGN(_(e_listidx), before);
14559 		l = NULL;
14560 	    }
14561 	}
14562 	if (l != NULL)
14563 	{
14564 	    list_insert_tv(l, &argvars[1], item);
14565 	    copy_tv(&argvars[0], rettv);
14566 	}
14567     }
14568 }
14569 
14570 /*
14571  * "invert(expr)" function
14572  */
14573     static void
14574 f_invert(typval_T *argvars, typval_T *rettv)
14575 {
14576     rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL);
14577 }
14578 
14579 /*
14580  * "isdirectory()" function
14581  */
14582     static void
14583 f_isdirectory(typval_T *argvars, typval_T *rettv)
14584 {
14585     rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0]));
14586 }
14587 
14588 /*
14589  * "islocked()" function
14590  */
14591     static void
14592 f_islocked(typval_T *argvars, typval_T *rettv)
14593 {
14594     lval_T	lv;
14595     char_u	*end;
14596     dictitem_T	*di;
14597 
14598     rettv->vval.v_number = -1;
14599     end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE,
14600 					GLV_NO_AUTOLOAD, FNE_CHECK_START);
14601     if (end != NULL && lv.ll_name != NULL)
14602     {
14603 	if (*end != NUL)
14604 	    EMSG(_(e_trailing));
14605 	else
14606 	{
14607 	    if (lv.ll_tv == NULL)
14608 	    {
14609 		if (check_changedtick(lv.ll_name))
14610 		    rettv->vval.v_number = 1;	    /* always locked */
14611 		else
14612 		{
14613 		    di = find_var(lv.ll_name, NULL, TRUE);
14614 		    if (di != NULL)
14615 		    {
14616 			/* Consider a variable locked when:
14617 			 * 1. the variable itself is locked
14618 			 * 2. the value of the variable is locked.
14619 			 * 3. the List or Dict value is locked.
14620 			 */
14621 			rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
14622 						  || tv_islocked(&di->di_tv));
14623 		    }
14624 		}
14625 	    }
14626 	    else if (lv.ll_range)
14627 		EMSG(_("E786: Range not allowed"));
14628 	    else if (lv.ll_newkey != NULL)
14629 		EMSG2(_(e_dictkey), lv.ll_newkey);
14630 	    else if (lv.ll_list != NULL)
14631 		/* List item. */
14632 		rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv);
14633 	    else
14634 		/* Dictionary item. */
14635 		rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv);
14636 	}
14637     }
14638 
14639     clear_lval(&lv);
14640 }
14641 
14642 #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
14643 /*
14644  * "isnan()" function
14645  */
14646     static void
14647 f_isnan(typval_T *argvars, typval_T *rettv)
14648 {
14649     rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT
14650 					    && isnan(argvars[0].vval.v_float);
14651 }
14652 #endif
14653 
14654 static void dict_list(typval_T *argvars, typval_T *rettv, int what);
14655 
14656 /*
14657  * Turn a dict into a list:
14658  * "what" == 0: list of keys
14659  * "what" == 1: list of values
14660  * "what" == 2: list of items
14661  */
14662     static void
14663 dict_list(typval_T *argvars, typval_T *rettv, int what)
14664 {
14665     list_T	*l2;
14666     dictitem_T	*di;
14667     hashitem_T	*hi;
14668     listitem_T	*li;
14669     listitem_T	*li2;
14670     dict_T	*d;
14671     int		todo;
14672 
14673     if (argvars[0].v_type != VAR_DICT)
14674     {
14675 	EMSG(_(e_dictreq));
14676 	return;
14677     }
14678     if ((d = argvars[0].vval.v_dict) == NULL)
14679 	return;
14680 
14681     if (rettv_list_alloc(rettv) == FAIL)
14682 	return;
14683 
14684     todo = (int)d->dv_hashtab.ht_used;
14685     for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
14686     {
14687 	if (!HASHITEM_EMPTY(hi))
14688 	{
14689 	    --todo;
14690 	    di = HI2DI(hi);
14691 
14692 	    li = listitem_alloc();
14693 	    if (li == NULL)
14694 		break;
14695 	    list_append(rettv->vval.v_list, li);
14696 
14697 	    if (what == 0)
14698 	    {
14699 		/* keys() */
14700 		li->li_tv.v_type = VAR_STRING;
14701 		li->li_tv.v_lock = 0;
14702 		li->li_tv.vval.v_string = vim_strsave(di->di_key);
14703 	    }
14704 	    else if (what == 1)
14705 	    {
14706 		/* values() */
14707 		copy_tv(&di->di_tv, &li->li_tv);
14708 	    }
14709 	    else
14710 	    {
14711 		/* items() */
14712 		l2 = list_alloc();
14713 		li->li_tv.v_type = VAR_LIST;
14714 		li->li_tv.v_lock = 0;
14715 		li->li_tv.vval.v_list = l2;
14716 		if (l2 == NULL)
14717 		    break;
14718 		++l2->lv_refcount;
14719 
14720 		li2 = listitem_alloc();
14721 		if (li2 == NULL)
14722 		    break;
14723 		list_append(l2, li2);
14724 		li2->li_tv.v_type = VAR_STRING;
14725 		li2->li_tv.v_lock = 0;
14726 		li2->li_tv.vval.v_string = vim_strsave(di->di_key);
14727 
14728 		li2 = listitem_alloc();
14729 		if (li2 == NULL)
14730 		    break;
14731 		list_append(l2, li2);
14732 		copy_tv(&di->di_tv, &li2->li_tv);
14733 	    }
14734 	}
14735     }
14736 }
14737 
14738 /*
14739  * "items(dict)" function
14740  */
14741     static void
14742 f_items(typval_T *argvars, typval_T *rettv)
14743 {
14744     dict_list(argvars, rettv, 2);
14745 }
14746 
14747 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
14748 /*
14749  * Get the job from the argument.
14750  * Returns NULL if the job is invalid.
14751  */
14752     static job_T *
14753 get_job_arg(typval_T *tv)
14754 {
14755     job_T *job;
14756 
14757     if (tv->v_type != VAR_JOB)
14758     {
14759 	EMSG2(_(e_invarg2), get_tv_string(tv));
14760 	return NULL;
14761     }
14762     job = tv->vval.v_job;
14763 
14764     if (job == NULL)
14765 	EMSG(_("E916: not a valid job"));
14766     return job;
14767 }
14768 
14769 /*
14770  * "job_getchannel()" function
14771  */
14772     static void
14773 f_job_getchannel(typval_T *argvars, typval_T *rettv)
14774 {
14775     job_T	*job = get_job_arg(&argvars[0]);
14776 
14777     if (job != NULL)
14778     {
14779 	rettv->v_type = VAR_CHANNEL;
14780 	rettv->vval.v_channel = job->jv_channel;
14781 	if (job->jv_channel != NULL)
14782 	    ++job->jv_channel->ch_refcount;
14783     }
14784 }
14785 
14786 /*
14787  * "job_info()" function
14788  */
14789     static void
14790 f_job_info(typval_T *argvars, typval_T *rettv)
14791 {
14792     job_T	*job = get_job_arg(&argvars[0]);
14793 
14794     if (job != NULL && rettv_dict_alloc(rettv) != FAIL)
14795 	job_info(job, rettv->vval.v_dict);
14796 }
14797 
14798 /*
14799  * "job_setoptions()" function
14800  */
14801     static void
14802 f_job_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
14803 {
14804     job_T	*job = get_job_arg(&argvars[0]);
14805     jobopt_T	opt;
14806 
14807     if (job == NULL)
14808 	return;
14809     clear_job_options(&opt);
14810     if (get_job_options(&argvars[1], &opt, JO_STOPONEXIT + JO_EXIT_CB) == FAIL)
14811 	return;
14812     job_set_options(job, &opt);
14813 }
14814 
14815 /*
14816  * "job_start()" function
14817  */
14818     static void
14819 f_job_start(typval_T *argvars, typval_T *rettv)
14820 {
14821     rettv->v_type = VAR_JOB;
14822     rettv->vval.v_job = job_start(argvars);
14823 }
14824 
14825 /*
14826  * "job_status()" function
14827  */
14828     static void
14829 f_job_status(typval_T *argvars, typval_T *rettv)
14830 {
14831     job_T	*job = get_job_arg(&argvars[0]);
14832 
14833     if (job != NULL)
14834     {
14835 	rettv->v_type = VAR_STRING;
14836 	rettv->vval.v_string = vim_strsave((char_u *)job_status(job));
14837     }
14838 }
14839 
14840 /*
14841  * "job_stop()" function
14842  */
14843     static void
14844 f_job_stop(typval_T *argvars, typval_T *rettv)
14845 {
14846     job_T	*job = get_job_arg(&argvars[0]);
14847 
14848     if (job != NULL)
14849 	rettv->vval.v_number = job_stop(job, argvars);
14850 }
14851 #endif
14852 
14853 /*
14854  * "join()" function
14855  */
14856     static void
14857 f_join(typval_T *argvars, typval_T *rettv)
14858 {
14859     garray_T	ga;
14860     char_u	*sep;
14861 
14862     if (argvars[0].v_type != VAR_LIST)
14863     {
14864 	EMSG(_(e_listreq));
14865 	return;
14866     }
14867     if (argvars[0].vval.v_list == NULL)
14868 	return;
14869     if (argvars[1].v_type == VAR_UNKNOWN)
14870 	sep = (char_u *)" ";
14871     else
14872 	sep = get_tv_string_chk(&argvars[1]);
14873 
14874     rettv->v_type = VAR_STRING;
14875 
14876     if (sep != NULL)
14877     {
14878 	ga_init2(&ga, (int)sizeof(char), 80);
14879 	list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0);
14880 	ga_append(&ga, NUL);
14881 	rettv->vval.v_string = (char_u *)ga.ga_data;
14882     }
14883     else
14884 	rettv->vval.v_string = NULL;
14885 }
14886 
14887 /*
14888  * "js_decode()" function
14889  */
14890     static void
14891 f_js_decode(typval_T *argvars, typval_T *rettv)
14892 {
14893     js_read_T	reader;
14894 
14895     reader.js_buf = get_tv_string(&argvars[0]);
14896     reader.js_fill = NULL;
14897     reader.js_used = 0;
14898     if (json_decode_all(&reader, rettv, JSON_JS) != OK)
14899 	EMSG(_(e_invarg));
14900 }
14901 
14902 /*
14903  * "js_encode()" function
14904  */
14905     static void
14906 f_js_encode(typval_T *argvars, typval_T *rettv)
14907 {
14908     rettv->v_type = VAR_STRING;
14909     rettv->vval.v_string = json_encode(&argvars[0], JSON_JS);
14910 }
14911 
14912 /*
14913  * "json_decode()" function
14914  */
14915     static void
14916 f_json_decode(typval_T *argvars, typval_T *rettv)
14917 {
14918     js_read_T	reader;
14919 
14920     reader.js_buf = get_tv_string(&argvars[0]);
14921     reader.js_fill = NULL;
14922     reader.js_used = 0;
14923     if (json_decode_all(&reader, rettv, 0) != OK)
14924 	EMSG(_(e_invarg));
14925 }
14926 
14927 /*
14928  * "json_encode()" function
14929  */
14930     static void
14931 f_json_encode(typval_T *argvars, typval_T *rettv)
14932 {
14933     rettv->v_type = VAR_STRING;
14934     rettv->vval.v_string = json_encode(&argvars[0], 0);
14935 }
14936 
14937 /*
14938  * "keys()" function
14939  */
14940     static void
14941 f_keys(typval_T *argvars, typval_T *rettv)
14942 {
14943     dict_list(argvars, rettv, 0);
14944 }
14945 
14946 /*
14947  * "last_buffer_nr()" function.
14948  */
14949     static void
14950 f_last_buffer_nr(typval_T *argvars UNUSED, typval_T *rettv)
14951 {
14952     int		n = 0;
14953     buf_T	*buf;
14954 
14955     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
14956 	if (n < buf->b_fnum)
14957 	    n = buf->b_fnum;
14958 
14959     rettv->vval.v_number = n;
14960 }
14961 
14962 /*
14963  * "len()" function
14964  */
14965     static void
14966 f_len(typval_T *argvars, typval_T *rettv)
14967 {
14968     switch (argvars[0].v_type)
14969     {
14970 	case VAR_STRING:
14971 	case VAR_NUMBER:
14972 	    rettv->vval.v_number = (varnumber_T)STRLEN(
14973 					       get_tv_string(&argvars[0]));
14974 	    break;
14975 	case VAR_LIST:
14976 	    rettv->vval.v_number = list_len(argvars[0].vval.v_list);
14977 	    break;
14978 	case VAR_DICT:
14979 	    rettv->vval.v_number = dict_len(argvars[0].vval.v_dict);
14980 	    break;
14981 	case VAR_UNKNOWN:
14982 	case VAR_SPECIAL:
14983 	case VAR_FLOAT:
14984 	case VAR_FUNC:
14985 	case VAR_PARTIAL:
14986 	case VAR_JOB:
14987 	case VAR_CHANNEL:
14988 	    EMSG(_("E701: Invalid type for len()"));
14989 	    break;
14990     }
14991 }
14992 
14993 static void libcall_common(typval_T *argvars, typval_T *rettv, int type);
14994 
14995     static void
14996 libcall_common(typval_T *argvars, typval_T *rettv, int type)
14997 {
14998 #ifdef FEAT_LIBCALL
14999     char_u		*string_in;
15000     char_u		**string_result;
15001     int			nr_result;
15002 #endif
15003 
15004     rettv->v_type = type;
15005     if (type != VAR_NUMBER)
15006 	rettv->vval.v_string = NULL;
15007 
15008     if (check_restricted() || check_secure())
15009 	return;
15010 
15011 #ifdef FEAT_LIBCALL
15012     /* The first two args must be strings, otherwise its meaningless */
15013     if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING)
15014     {
15015 	string_in = NULL;
15016 	if (argvars[2].v_type == VAR_STRING)
15017 	    string_in = argvars[2].vval.v_string;
15018 	if (type == VAR_NUMBER)
15019 	    string_result = NULL;
15020 	else
15021 	    string_result = &rettv->vval.v_string;
15022 	if (mch_libcall(argvars[0].vval.v_string,
15023 			     argvars[1].vval.v_string,
15024 			     string_in,
15025 			     argvars[2].vval.v_number,
15026 			     string_result,
15027 			     &nr_result) == OK
15028 		&& type == VAR_NUMBER)
15029 	    rettv->vval.v_number = nr_result;
15030     }
15031 #endif
15032 }
15033 
15034 /*
15035  * "libcall()" function
15036  */
15037     static void
15038 f_libcall(typval_T *argvars, typval_T *rettv)
15039 {
15040     libcall_common(argvars, rettv, VAR_STRING);
15041 }
15042 
15043 /*
15044  * "libcallnr()" function
15045  */
15046     static void
15047 f_libcallnr(typval_T *argvars, typval_T *rettv)
15048 {
15049     libcall_common(argvars, rettv, VAR_NUMBER);
15050 }
15051 
15052 /*
15053  * "line(string)" function
15054  */
15055     static void
15056 f_line(typval_T *argvars, typval_T *rettv)
15057 {
15058     linenr_T	lnum = 0;
15059     pos_T	*fp;
15060     int		fnum;
15061 
15062     fp = var2fpos(&argvars[0], TRUE, &fnum);
15063     if (fp != NULL)
15064 	lnum = fp->lnum;
15065     rettv->vval.v_number = lnum;
15066 }
15067 
15068 /*
15069  * "line2byte(lnum)" function
15070  */
15071     static void
15072 f_line2byte(typval_T *argvars UNUSED, typval_T *rettv)
15073 {
15074 #ifndef FEAT_BYTEOFF
15075     rettv->vval.v_number = -1;
15076 #else
15077     linenr_T	lnum;
15078 
15079     lnum = get_tv_lnum(argvars);
15080     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
15081 	rettv->vval.v_number = -1;
15082     else
15083 	rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL);
15084     if (rettv->vval.v_number >= 0)
15085 	++rettv->vval.v_number;
15086 #endif
15087 }
15088 
15089 /*
15090  * "lispindent(lnum)" function
15091  */
15092     static void
15093 f_lispindent(typval_T *argvars UNUSED, typval_T *rettv)
15094 {
15095 #ifdef FEAT_LISP
15096     pos_T	pos;
15097     linenr_T	lnum;
15098 
15099     pos = curwin->w_cursor;
15100     lnum = get_tv_lnum(argvars);
15101     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
15102     {
15103 	curwin->w_cursor.lnum = lnum;
15104 	rettv->vval.v_number = get_lisp_indent();
15105 	curwin->w_cursor = pos;
15106     }
15107     else
15108 #endif
15109 	rettv->vval.v_number = -1;
15110 }
15111 
15112 /*
15113  * "localtime()" function
15114  */
15115     static void
15116 f_localtime(typval_T *argvars UNUSED, typval_T *rettv)
15117 {
15118     rettv->vval.v_number = (varnumber_T)time(NULL);
15119 }
15120 
15121 static void get_maparg(typval_T *argvars, typval_T *rettv, int exact);
15122 
15123     static void
15124 get_maparg(typval_T *argvars, typval_T *rettv, int exact)
15125 {
15126     char_u	*keys;
15127     char_u	*which;
15128     char_u	buf[NUMBUFLEN];
15129     char_u	*keys_buf = NULL;
15130     char_u	*rhs;
15131     int		mode;
15132     int		abbr = FALSE;
15133     int		get_dict = FALSE;
15134     mapblock_T	*mp;
15135     int		buffer_local;
15136 
15137     /* return empty string for failure */
15138     rettv->v_type = VAR_STRING;
15139     rettv->vval.v_string = NULL;
15140 
15141     keys = get_tv_string(&argvars[0]);
15142     if (*keys == NUL)
15143 	return;
15144 
15145     if (argvars[1].v_type != VAR_UNKNOWN)
15146     {
15147 	which = get_tv_string_buf_chk(&argvars[1], buf);
15148 	if (argvars[2].v_type != VAR_UNKNOWN)
15149 	{
15150 	    abbr = get_tv_number(&argvars[2]);
15151 	    if (argvars[3].v_type != VAR_UNKNOWN)
15152 		get_dict = get_tv_number(&argvars[3]);
15153 	}
15154     }
15155     else
15156 	which = (char_u *)"";
15157     if (which == NULL)
15158 	return;
15159 
15160     mode = get_map_mode(&which, 0);
15161 
15162     keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE);
15163     rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local);
15164     vim_free(keys_buf);
15165 
15166     if (!get_dict)
15167     {
15168 	/* Return a string. */
15169 	if (rhs != NULL)
15170 	    rettv->vval.v_string = str2special_save(rhs, FALSE);
15171 
15172     }
15173     else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL)
15174     {
15175 	/* Return a dictionary. */
15176 	char_u	    *lhs = str2special_save(mp->m_keys, TRUE);
15177 	char_u	    *mapmode = map_mode_to_chars(mp->m_mode);
15178 	dict_T	    *dict = rettv->vval.v_dict;
15179 
15180 	dict_add_nr_str(dict, "lhs",	 0L, lhs);
15181 	dict_add_nr_str(dict, "rhs",     0L, mp->m_orig_str);
15182 	dict_add_nr_str(dict, "noremap", mp->m_noremap ? 1L : 0L , NULL);
15183 	dict_add_nr_str(dict, "expr",    mp->m_expr    ? 1L : 0L, NULL);
15184 	dict_add_nr_str(dict, "silent",  mp->m_silent  ? 1L : 0L, NULL);
15185 	dict_add_nr_str(dict, "sid",     (long)mp->m_script_ID, NULL);
15186 	dict_add_nr_str(dict, "buffer",  (long)buffer_local, NULL);
15187 	dict_add_nr_str(dict, "nowait",  mp->m_nowait  ? 1L : 0L, NULL);
15188 	dict_add_nr_str(dict, "mode",    0L, mapmode);
15189 
15190 	vim_free(lhs);
15191 	vim_free(mapmode);
15192     }
15193 }
15194 
15195 #ifdef FEAT_FLOAT
15196 /*
15197  * "log()" function
15198  */
15199     static void
15200 f_log(typval_T *argvars, typval_T *rettv)
15201 {
15202     float_T	f = 0.0;
15203 
15204     rettv->v_type = VAR_FLOAT;
15205     if (get_float_arg(argvars, &f) == OK)
15206 	rettv->vval.v_float = log(f);
15207     else
15208 	rettv->vval.v_float = 0.0;
15209 }
15210 
15211 /*
15212  * "log10()" function
15213  */
15214     static void
15215 f_log10(typval_T *argvars, typval_T *rettv)
15216 {
15217     float_T	f = 0.0;
15218 
15219     rettv->v_type = VAR_FLOAT;
15220     if (get_float_arg(argvars, &f) == OK)
15221 	rettv->vval.v_float = log10(f);
15222     else
15223 	rettv->vval.v_float = 0.0;
15224 }
15225 #endif
15226 
15227 #ifdef FEAT_LUA
15228 /*
15229  * "luaeval()" function
15230  */
15231     static void
15232 f_luaeval(typval_T *argvars, typval_T *rettv)
15233 {
15234     char_u	*str;
15235     char_u	buf[NUMBUFLEN];
15236 
15237     str = get_tv_string_buf(&argvars[0], buf);
15238     do_luaeval(str, argvars + 1, rettv);
15239 }
15240 #endif
15241 
15242 /*
15243  * "map()" function
15244  */
15245     static void
15246 f_map(typval_T *argvars, typval_T *rettv)
15247 {
15248     filter_map(argvars, rettv, TRUE);
15249 }
15250 
15251 /*
15252  * "maparg()" function
15253  */
15254     static void
15255 f_maparg(typval_T *argvars, typval_T *rettv)
15256 {
15257     get_maparg(argvars, rettv, TRUE);
15258 }
15259 
15260 /*
15261  * "mapcheck()" function
15262  */
15263     static void
15264 f_mapcheck(typval_T *argvars, typval_T *rettv)
15265 {
15266     get_maparg(argvars, rettv, FALSE);
15267 }
15268 
15269 static void find_some_match(typval_T *argvars, typval_T *rettv, int start);
15270 
15271     static void
15272 find_some_match(typval_T *argvars, typval_T *rettv, int type)
15273 {
15274     char_u	*str = NULL;
15275     long	len = 0;
15276     char_u	*expr = NULL;
15277     char_u	*pat;
15278     regmatch_T	regmatch;
15279     char_u	patbuf[NUMBUFLEN];
15280     char_u	strbuf[NUMBUFLEN];
15281     char_u	*save_cpo;
15282     long	start = 0;
15283     long	nth = 1;
15284     colnr_T	startcol = 0;
15285     int		match = 0;
15286     list_T	*l = NULL;
15287     listitem_T	*li = NULL;
15288     long	idx = 0;
15289     char_u	*tofree = NULL;
15290 
15291     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
15292     save_cpo = p_cpo;
15293     p_cpo = (char_u *)"";
15294 
15295     rettv->vval.v_number = -1;
15296     if (type == 3)
15297     {
15298 	/* return empty list when there are no matches */
15299 	if (rettv_list_alloc(rettv) == FAIL)
15300 	    goto theend;
15301     }
15302     else if (type == 2)
15303     {
15304 	rettv->v_type = VAR_STRING;
15305 	rettv->vval.v_string = NULL;
15306     }
15307 
15308     if (argvars[0].v_type == VAR_LIST)
15309     {
15310 	if ((l = argvars[0].vval.v_list) == NULL)
15311 	    goto theend;
15312 	li = l->lv_first;
15313     }
15314     else
15315     {
15316 	expr = str = get_tv_string(&argvars[0]);
15317 	len = (long)STRLEN(str);
15318     }
15319 
15320     pat = get_tv_string_buf_chk(&argvars[1], patbuf);
15321     if (pat == NULL)
15322 	goto theend;
15323 
15324     if (argvars[2].v_type != VAR_UNKNOWN)
15325     {
15326 	int	    error = FALSE;
15327 
15328 	start = get_tv_number_chk(&argvars[2], &error);
15329 	if (error)
15330 	    goto theend;
15331 	if (l != NULL)
15332 	{
15333 	    li = list_find(l, start);
15334 	    if (li == NULL)
15335 		goto theend;
15336 	    idx = l->lv_idx;	/* use the cached index */
15337 	}
15338 	else
15339 	{
15340 	    if (start < 0)
15341 		start = 0;
15342 	    if (start > len)
15343 		goto theend;
15344 	    /* When "count" argument is there ignore matches before "start",
15345 	     * otherwise skip part of the string.  Differs when pattern is "^"
15346 	     * or "\<". */
15347 	    if (argvars[3].v_type != VAR_UNKNOWN)
15348 		startcol = start;
15349 	    else
15350 	    {
15351 		str += start;
15352 		len -= start;
15353 	    }
15354 	}
15355 
15356 	if (argvars[3].v_type != VAR_UNKNOWN)
15357 	    nth = get_tv_number_chk(&argvars[3], &error);
15358 	if (error)
15359 	    goto theend;
15360     }
15361 
15362     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
15363     if (regmatch.regprog != NULL)
15364     {
15365 	regmatch.rm_ic = p_ic;
15366 
15367 	for (;;)
15368 	{
15369 	    if (l != NULL)
15370 	    {
15371 		if (li == NULL)
15372 		{
15373 		    match = FALSE;
15374 		    break;
15375 		}
15376 		vim_free(tofree);
15377 		str = echo_string(&li->li_tv, &tofree, strbuf, 0);
15378 		if (str == NULL)
15379 		    break;
15380 	    }
15381 
15382 	    match = vim_regexec_nl(&regmatch, str, (colnr_T)startcol);
15383 
15384 	    if (match && --nth <= 0)
15385 		break;
15386 	    if (l == NULL && !match)
15387 		break;
15388 
15389 	    /* Advance to just after the match. */
15390 	    if (l != NULL)
15391 	    {
15392 		li = li->li_next;
15393 		++idx;
15394 	    }
15395 	    else
15396 	    {
15397 #ifdef FEAT_MBYTE
15398 		startcol = (colnr_T)(regmatch.startp[0]
15399 				    + (*mb_ptr2len)(regmatch.startp[0]) - str);
15400 #else
15401 		startcol = (colnr_T)(regmatch.startp[0] + 1 - str);
15402 #endif
15403 		if (startcol > (colnr_T)len
15404 				      || str + startcol <= regmatch.startp[0])
15405 		{
15406 		    match = FALSE;
15407 		    break;
15408 		}
15409 	    }
15410 	}
15411 
15412 	if (match)
15413 	{
15414 	    if (type == 3)
15415 	    {
15416 		int i;
15417 
15418 		/* return list with matched string and submatches */
15419 		for (i = 0; i < NSUBEXP; ++i)
15420 		{
15421 		    if (regmatch.endp[i] == NULL)
15422 		    {
15423 			if (list_append_string(rettv->vval.v_list,
15424 						     (char_u *)"", 0) == FAIL)
15425 			    break;
15426 		    }
15427 		    else if (list_append_string(rettv->vval.v_list,
15428 				regmatch.startp[i],
15429 				(int)(regmatch.endp[i] - regmatch.startp[i]))
15430 			    == FAIL)
15431 			break;
15432 		}
15433 	    }
15434 	    else if (type == 2)
15435 	    {
15436 		/* return matched string */
15437 		if (l != NULL)
15438 		    copy_tv(&li->li_tv, rettv);
15439 		else
15440 		    rettv->vval.v_string = vim_strnsave(regmatch.startp[0],
15441 				(int)(regmatch.endp[0] - regmatch.startp[0]));
15442 	    }
15443 	    else if (l != NULL)
15444 		rettv->vval.v_number = idx;
15445 	    else
15446 	    {
15447 		if (type != 0)
15448 		    rettv->vval.v_number =
15449 				      (varnumber_T)(regmatch.startp[0] - str);
15450 		else
15451 		    rettv->vval.v_number =
15452 					(varnumber_T)(regmatch.endp[0] - str);
15453 		rettv->vval.v_number += (varnumber_T)(str - expr);
15454 	    }
15455 	}
15456 	vim_regfree(regmatch.regprog);
15457     }
15458 
15459 theend:
15460     vim_free(tofree);
15461     p_cpo = save_cpo;
15462 }
15463 
15464 /*
15465  * "match()" function
15466  */
15467     static void
15468 f_match(typval_T *argvars, typval_T *rettv)
15469 {
15470     find_some_match(argvars, rettv, 1);
15471 }
15472 
15473 /*
15474  * "matchadd()" function
15475  */
15476     static void
15477 f_matchadd(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
15478 {
15479 #ifdef FEAT_SEARCH_EXTRA
15480     char_u	buf[NUMBUFLEN];
15481     char_u	*grp = get_tv_string_buf_chk(&argvars[0], buf);	/* group */
15482     char_u	*pat = get_tv_string_buf_chk(&argvars[1], buf);	/* pattern */
15483     int		prio = 10;	/* default priority */
15484     int		id = -1;
15485     int		error = FALSE;
15486     char_u	*conceal_char = NULL;
15487 
15488     rettv->vval.v_number = -1;
15489 
15490     if (grp == NULL || pat == NULL)
15491 	return;
15492     if (argvars[2].v_type != VAR_UNKNOWN)
15493     {
15494 	prio = get_tv_number_chk(&argvars[2], &error);
15495 	if (argvars[3].v_type != VAR_UNKNOWN)
15496 	{
15497 	    id = get_tv_number_chk(&argvars[3], &error);
15498 	    if (argvars[4].v_type != VAR_UNKNOWN)
15499 	    {
15500 		if (argvars[4].v_type != VAR_DICT)
15501 		{
15502 		    EMSG(_(e_dictreq));
15503 		    return;
15504 		}
15505 		if (dict_find(argvars[4].vval.v_dict,
15506 					     (char_u *)"conceal", -1) != NULL)
15507 		    conceal_char = get_dict_string(argvars[4].vval.v_dict,
15508 						  (char_u *)"conceal", FALSE);
15509 	    }
15510 	}
15511     }
15512     if (error == TRUE)
15513 	return;
15514     if (id >= 1 && id <= 3)
15515     {
15516 	EMSGN("E798: ID is reserved for \":match\": %ld", id);
15517 	return;
15518     }
15519 
15520     rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL,
15521 								conceal_char);
15522 #endif
15523 }
15524 
15525 /*
15526  * "matchaddpos()" function
15527  */
15528     static void
15529 f_matchaddpos(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
15530 {
15531 #ifdef FEAT_SEARCH_EXTRA
15532     char_u	buf[NUMBUFLEN];
15533     char_u	*group;
15534     int		prio = 10;
15535     int		id = -1;
15536     int		error = FALSE;
15537     list_T	*l;
15538     char_u	*conceal_char = NULL;
15539 
15540     rettv->vval.v_number = -1;
15541 
15542     group = get_tv_string_buf_chk(&argvars[0], buf);
15543     if (group == NULL)
15544 	return;
15545 
15546     if (argvars[1].v_type != VAR_LIST)
15547     {
15548 	EMSG2(_(e_listarg), "matchaddpos()");
15549 	return;
15550     }
15551     l = argvars[1].vval.v_list;
15552     if (l == NULL)
15553 	return;
15554 
15555     if (argvars[2].v_type != VAR_UNKNOWN)
15556     {
15557 	prio = get_tv_number_chk(&argvars[2], &error);
15558 	if (argvars[3].v_type != VAR_UNKNOWN)
15559 	{
15560 	    id = get_tv_number_chk(&argvars[3], &error);
15561 	    if (argvars[4].v_type != VAR_UNKNOWN)
15562 	    {
15563 		if (argvars[4].v_type != VAR_DICT)
15564 		{
15565 		    EMSG(_(e_dictreq));
15566 		    return;
15567 		}
15568 		if (dict_find(argvars[4].vval.v_dict,
15569 					     (char_u *)"conceal", -1) != NULL)
15570 		    conceal_char = get_dict_string(argvars[4].vval.v_dict,
15571 						  (char_u *)"conceal", FALSE);
15572 	    }
15573 	}
15574     }
15575     if (error == TRUE)
15576 	return;
15577 
15578     /* id == 3 is ok because matchaddpos() is supposed to substitute :3match */
15579     if (id == 1 || id == 2)
15580     {
15581 	EMSGN("E798: ID is reserved for \":match\": %ld", id);
15582 	return;
15583     }
15584 
15585     rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l,
15586 								conceal_char);
15587 #endif
15588 }
15589 
15590 /*
15591  * "matcharg()" function
15592  */
15593     static void
15594 f_matcharg(typval_T *argvars UNUSED, typval_T *rettv)
15595 {
15596     if (rettv_list_alloc(rettv) == OK)
15597     {
15598 #ifdef FEAT_SEARCH_EXTRA
15599 	int	    id = get_tv_number(&argvars[0]);
15600 	matchitem_T *m;
15601 
15602 	if (id >= 1 && id <= 3)
15603 	{
15604 	    if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
15605 	    {
15606 		list_append_string(rettv->vval.v_list,
15607 						syn_id2name(m->hlg_id), -1);
15608 		list_append_string(rettv->vval.v_list, m->pattern, -1);
15609 	    }
15610 	    else
15611 	    {
15612 		list_append_string(rettv->vval.v_list, NULL, -1);
15613 		list_append_string(rettv->vval.v_list, NULL, -1);
15614 	    }
15615 	}
15616 #endif
15617     }
15618 }
15619 
15620 /*
15621  * "matchdelete()" function
15622  */
15623     static void
15624 f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
15625 {
15626 #ifdef FEAT_SEARCH_EXTRA
15627     rettv->vval.v_number = match_delete(curwin,
15628 				       (int)get_tv_number(&argvars[0]), TRUE);
15629 #endif
15630 }
15631 
15632 /*
15633  * "matchend()" function
15634  */
15635     static void
15636 f_matchend(typval_T *argvars, typval_T *rettv)
15637 {
15638     find_some_match(argvars, rettv, 0);
15639 }
15640 
15641 /*
15642  * "matchlist()" function
15643  */
15644     static void
15645 f_matchlist(typval_T *argvars, typval_T *rettv)
15646 {
15647     find_some_match(argvars, rettv, 3);
15648 }
15649 
15650 /*
15651  * "matchstr()" function
15652  */
15653     static void
15654 f_matchstr(typval_T *argvars, typval_T *rettv)
15655 {
15656     find_some_match(argvars, rettv, 2);
15657 }
15658 
15659 static void max_min(typval_T *argvars, typval_T *rettv, int domax);
15660 
15661     static void
15662 max_min(typval_T *argvars, typval_T *rettv, int domax)
15663 {
15664     long	n = 0;
15665     long	i;
15666     int		error = FALSE;
15667 
15668     if (argvars[0].v_type == VAR_LIST)
15669     {
15670 	list_T		*l;
15671 	listitem_T	*li;
15672 
15673 	l = argvars[0].vval.v_list;
15674 	if (l != NULL)
15675 	{
15676 	    li = l->lv_first;
15677 	    if (li != NULL)
15678 	    {
15679 		n = get_tv_number_chk(&li->li_tv, &error);
15680 		for (;;)
15681 		{
15682 		    li = li->li_next;
15683 		    if (li == NULL)
15684 			break;
15685 		    i = get_tv_number_chk(&li->li_tv, &error);
15686 		    if (domax ? i > n : i < n)
15687 			n = i;
15688 		}
15689 	    }
15690 	}
15691     }
15692     else if (argvars[0].v_type == VAR_DICT)
15693     {
15694 	dict_T		*d;
15695 	int		first = TRUE;
15696 	hashitem_T	*hi;
15697 	int		todo;
15698 
15699 	d = argvars[0].vval.v_dict;
15700 	if (d != NULL)
15701 	{
15702 	    todo = (int)d->dv_hashtab.ht_used;
15703 	    for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi)
15704 	    {
15705 		if (!HASHITEM_EMPTY(hi))
15706 		{
15707 		    --todo;
15708 		    i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error);
15709 		    if (first)
15710 		    {
15711 			n = i;
15712 			first = FALSE;
15713 		    }
15714 		    else if (domax ? i > n : i < n)
15715 			n = i;
15716 		}
15717 	    }
15718 	}
15719     }
15720     else
15721 	EMSG(_(e_listdictarg));
15722     rettv->vval.v_number = error ? 0 : n;
15723 }
15724 
15725 /*
15726  * "max()" function
15727  */
15728     static void
15729 f_max(typval_T *argvars, typval_T *rettv)
15730 {
15731     max_min(argvars, rettv, TRUE);
15732 }
15733 
15734 /*
15735  * "min()" function
15736  */
15737     static void
15738 f_min(typval_T *argvars, typval_T *rettv)
15739 {
15740     max_min(argvars, rettv, FALSE);
15741 }
15742 
15743 static int mkdir_recurse(char_u *dir, int prot);
15744 
15745 /*
15746  * Create the directory in which "dir" is located, and higher levels when
15747  * needed.
15748  */
15749     static int
15750 mkdir_recurse(char_u *dir, int prot)
15751 {
15752     char_u	*p;
15753     char_u	*updir;
15754     int		r = FAIL;
15755 
15756     /* Get end of directory name in "dir".
15757      * We're done when it's "/" or "c:/". */
15758     p = gettail_sep(dir);
15759     if (p <= get_past_head(dir))
15760 	return OK;
15761 
15762     /* If the directory exists we're done.  Otherwise: create it.*/
15763     updir = vim_strnsave(dir, (int)(p - dir));
15764     if (updir == NULL)
15765 	return FAIL;
15766     if (mch_isdir(updir))
15767 	r = OK;
15768     else if (mkdir_recurse(updir, prot) == OK)
15769 	r = vim_mkdir_emsg(updir, prot);
15770     vim_free(updir);
15771     return r;
15772 }
15773 
15774 #ifdef vim_mkdir
15775 /*
15776  * "mkdir()" function
15777  */
15778     static void
15779 f_mkdir(typval_T *argvars, typval_T *rettv)
15780 {
15781     char_u	*dir;
15782     char_u	buf[NUMBUFLEN];
15783     int		prot = 0755;
15784 
15785     rettv->vval.v_number = FAIL;
15786     if (check_restricted() || check_secure())
15787 	return;
15788 
15789     dir = get_tv_string_buf(&argvars[0], buf);
15790     if (*dir == NUL)
15791 	rettv->vval.v_number = FAIL;
15792     else
15793     {
15794 	if (*gettail(dir) == NUL)
15795 	    /* remove trailing slashes */
15796 	    *gettail_sep(dir) = NUL;
15797 
15798 	if (argvars[1].v_type != VAR_UNKNOWN)
15799 	{
15800 	    if (argvars[2].v_type != VAR_UNKNOWN)
15801 		prot = get_tv_number_chk(&argvars[2], NULL);
15802 	    if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0)
15803 		mkdir_recurse(dir, prot);
15804 	}
15805 	rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot);
15806     }
15807 }
15808 #endif
15809 
15810 /*
15811  * "mode()" function
15812  */
15813     static void
15814 f_mode(typval_T *argvars, typval_T *rettv)
15815 {
15816     char_u	buf[3];
15817 
15818     buf[1] = NUL;
15819     buf[2] = NUL;
15820 
15821     if (VIsual_active)
15822     {
15823 	if (VIsual_select)
15824 	    buf[0] = VIsual_mode + 's' - 'v';
15825 	else
15826 	    buf[0] = VIsual_mode;
15827     }
15828     else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
15829 		|| State == CONFIRM)
15830     {
15831 	buf[0] = 'r';
15832 	if (State == ASKMORE)
15833 	    buf[1] = 'm';
15834 	else if (State == CONFIRM)
15835 	    buf[1] = '?';
15836     }
15837     else if (State == EXTERNCMD)
15838 	buf[0] = '!';
15839     else if (State & INSERT)
15840     {
15841 #ifdef FEAT_VREPLACE
15842 	if (State & VREPLACE_FLAG)
15843 	{
15844 	    buf[0] = 'R';
15845 	    buf[1] = 'v';
15846 	}
15847 	else
15848 #endif
15849 	if (State & REPLACE_FLAG)
15850 	    buf[0] = 'R';
15851 	else
15852 	    buf[0] = 'i';
15853     }
15854     else if (State & CMDLINE)
15855     {
15856 	buf[0] = 'c';
15857 	if (exmode_active)
15858 	    buf[1] = 'v';
15859     }
15860     else if (exmode_active)
15861     {
15862 	buf[0] = 'c';
15863 	buf[1] = 'e';
15864     }
15865     else
15866     {
15867 	buf[0] = 'n';
15868 	if (finish_op)
15869 	    buf[1] = 'o';
15870     }
15871 
15872     /* Clear out the minor mode when the argument is not a non-zero number or
15873      * non-empty string.  */
15874     if (!non_zero_arg(&argvars[0]))
15875 	buf[1] = NUL;
15876 
15877     rettv->vval.v_string = vim_strsave(buf);
15878     rettv->v_type = VAR_STRING;
15879 }
15880 
15881 #if defined(FEAT_MZSCHEME) || defined(PROTO)
15882 /*
15883  * "mzeval()" function
15884  */
15885     static void
15886 f_mzeval(typval_T *argvars, typval_T *rettv)
15887 {
15888     char_u	*str;
15889     char_u	buf[NUMBUFLEN];
15890 
15891     str = get_tv_string_buf(&argvars[0], buf);
15892     do_mzeval(str, rettv);
15893 }
15894 
15895     void
15896 mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv)
15897 {
15898     typval_T argvars[3];
15899 
15900     argvars[0].v_type = VAR_STRING;
15901     argvars[0].vval.v_string = name;
15902     copy_tv(args, &argvars[1]);
15903     argvars[2].v_type = VAR_UNKNOWN;
15904     f_call(argvars, rettv);
15905     clear_tv(&argvars[1]);
15906 }
15907 #endif
15908 
15909 /*
15910  * "nextnonblank()" function
15911  */
15912     static void
15913 f_nextnonblank(typval_T *argvars, typval_T *rettv)
15914 {
15915     linenr_T	lnum;
15916 
15917     for (lnum = get_tv_lnum(argvars); ; ++lnum)
15918     {
15919 	if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count)
15920 	{
15921 	    lnum = 0;
15922 	    break;
15923 	}
15924 	if (*skipwhite(ml_get(lnum)) != NUL)
15925 	    break;
15926     }
15927     rettv->vval.v_number = lnum;
15928 }
15929 
15930 /*
15931  * "nr2char()" function
15932  */
15933     static void
15934 f_nr2char(typval_T *argvars, typval_T *rettv)
15935 {
15936     char_u	buf[NUMBUFLEN];
15937 
15938 #ifdef FEAT_MBYTE
15939     if (has_mbyte)
15940     {
15941 	int	utf8 = 0;
15942 
15943 	if (argvars[1].v_type != VAR_UNKNOWN)
15944 	    utf8 = get_tv_number_chk(&argvars[1], NULL);
15945 	if (utf8)
15946 	    buf[(*utf_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
15947 	else
15948 	    buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
15949     }
15950     else
15951 #endif
15952     {
15953 	buf[0] = (char_u)get_tv_number(&argvars[0]);
15954 	buf[1] = NUL;
15955     }
15956     rettv->v_type = VAR_STRING;
15957     rettv->vval.v_string = vim_strsave(buf);
15958 }
15959 
15960 /*
15961  * "or(expr, expr)" function
15962  */
15963     static void
15964 f_or(typval_T *argvars, typval_T *rettv)
15965 {
15966     rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
15967 					| get_tv_number_chk(&argvars[1], NULL);
15968 }
15969 
15970 /*
15971  * "pathshorten()" function
15972  */
15973     static void
15974 f_pathshorten(typval_T *argvars, typval_T *rettv)
15975 {
15976     char_u	*p;
15977 
15978     rettv->v_type = VAR_STRING;
15979     p = get_tv_string_chk(&argvars[0]);
15980     if (p == NULL)
15981 	rettv->vval.v_string = NULL;
15982     else
15983     {
15984 	p = vim_strsave(p);
15985 	rettv->vval.v_string = p;
15986 	if (p != NULL)
15987 	    shorten_dir(p);
15988     }
15989 }
15990 
15991 #ifdef FEAT_PERL
15992 /*
15993  * "perleval()" function
15994  */
15995     static void
15996 f_perleval(typval_T *argvars, typval_T *rettv)
15997 {
15998     char_u	*str;
15999     char_u	buf[NUMBUFLEN];
16000 
16001     str = get_tv_string_buf(&argvars[0], buf);
16002     do_perleval(str, rettv);
16003 }
16004 #endif
16005 
16006 #ifdef FEAT_FLOAT
16007 /*
16008  * "pow()" function
16009  */
16010     static void
16011 f_pow(typval_T *argvars, typval_T *rettv)
16012 {
16013     float_T	fx = 0.0, fy = 0.0;
16014 
16015     rettv->v_type = VAR_FLOAT;
16016     if (get_float_arg(argvars, &fx) == OK
16017 				     && get_float_arg(&argvars[1], &fy) == OK)
16018 	rettv->vval.v_float = pow(fx, fy);
16019     else
16020 	rettv->vval.v_float = 0.0;
16021 }
16022 #endif
16023 
16024 /*
16025  * "prevnonblank()" function
16026  */
16027     static void
16028 f_prevnonblank(typval_T *argvars, typval_T *rettv)
16029 {
16030     linenr_T	lnum;
16031 
16032     lnum = get_tv_lnum(argvars);
16033     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
16034 	lnum = 0;
16035     else
16036 	while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
16037 	    --lnum;
16038     rettv->vval.v_number = lnum;
16039 }
16040 
16041 /* This dummy va_list is here because:
16042  * - passing a NULL pointer doesn't work when va_list isn't a pointer
16043  * - locally in the function results in a "used before set" warning
16044  * - using va_start() to initialize it gives "function with fixed args" error */
16045 static va_list	ap;
16046 
16047 /*
16048  * "printf()" function
16049  */
16050     static void
16051 f_printf(typval_T *argvars, typval_T *rettv)
16052 {
16053     char_u	buf[NUMBUFLEN];
16054     int		len;
16055     char_u	*s;
16056     int		saved_did_emsg = did_emsg;
16057     char	*fmt;
16058 
16059     rettv->v_type = VAR_STRING;
16060     rettv->vval.v_string = NULL;
16061 
16062     /* Get the required length, allocate the buffer and do it for real. */
16063     did_emsg = FALSE;
16064     fmt = (char *)get_tv_string_buf(&argvars[0], buf);
16065     len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1);
16066     if (!did_emsg)
16067     {
16068 	s = alloc(len + 1);
16069 	if (s != NULL)
16070 	{
16071 	    rettv->vval.v_string = s;
16072 	    (void)vim_vsnprintf((char *)s, len + 1, fmt, ap, argvars + 1);
16073 	}
16074     }
16075     did_emsg |= saved_did_emsg;
16076 }
16077 
16078 /*
16079  * "pumvisible()" function
16080  */
16081     static void
16082 f_pumvisible(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
16083 {
16084 #ifdef FEAT_INS_EXPAND
16085     if (pum_visible())
16086 	rettv->vval.v_number = 1;
16087 #endif
16088 }
16089 
16090 #ifdef FEAT_PYTHON3
16091 /*
16092  * "py3eval()" function
16093  */
16094     static void
16095 f_py3eval(typval_T *argvars, typval_T *rettv)
16096 {
16097     char_u	*str;
16098     char_u	buf[NUMBUFLEN];
16099 
16100     str = get_tv_string_buf(&argvars[0], buf);
16101     do_py3eval(str, rettv);
16102 }
16103 #endif
16104 
16105 #ifdef FEAT_PYTHON
16106 /*
16107  * "pyeval()" function
16108  */
16109     static void
16110 f_pyeval(typval_T *argvars, typval_T *rettv)
16111 {
16112     char_u	*str;
16113     char_u	buf[NUMBUFLEN];
16114 
16115     str = get_tv_string_buf(&argvars[0], buf);
16116     do_pyeval(str, rettv);
16117 }
16118 #endif
16119 
16120 /*
16121  * "range()" function
16122  */
16123     static void
16124 f_range(typval_T *argvars, typval_T *rettv)
16125 {
16126     long	start;
16127     long	end;
16128     long	stride = 1;
16129     long	i;
16130     int		error = FALSE;
16131 
16132     start = get_tv_number_chk(&argvars[0], &error);
16133     if (argvars[1].v_type == VAR_UNKNOWN)
16134     {
16135 	end = start - 1;
16136 	start = 0;
16137     }
16138     else
16139     {
16140 	end = get_tv_number_chk(&argvars[1], &error);
16141 	if (argvars[2].v_type != VAR_UNKNOWN)
16142 	    stride = get_tv_number_chk(&argvars[2], &error);
16143     }
16144 
16145     if (error)
16146 	return;		/* type error; errmsg already given */
16147     if (stride == 0)
16148 	EMSG(_("E726: Stride is zero"));
16149     else if (stride > 0 ? end + 1 < start : end - 1 > start)
16150 	EMSG(_("E727: Start past end"));
16151     else
16152     {
16153 	if (rettv_list_alloc(rettv) == OK)
16154 	    for (i = start; stride > 0 ? i <= end : i >= end; i += stride)
16155 		if (list_append_number(rettv->vval.v_list,
16156 						      (varnumber_T)i) == FAIL)
16157 		    break;
16158     }
16159 }
16160 
16161 /*
16162  * "readfile()" function
16163  */
16164     static void
16165 f_readfile(typval_T *argvars, typval_T *rettv)
16166 {
16167     int		binary = FALSE;
16168     int		failed = FALSE;
16169     char_u	*fname;
16170     FILE	*fd;
16171     char_u	buf[(IOSIZE/256)*256];	/* rounded to avoid odd + 1 */
16172     int		io_size = sizeof(buf);
16173     int		readlen;		/* size of last fread() */
16174     char_u	*prev	 = NULL;	/* previously read bytes, if any */
16175     long	prevlen  = 0;		/* length of data in prev */
16176     long	prevsize = 0;		/* size of prev buffer */
16177     long	maxline  = MAXLNUM;
16178     long	cnt	 = 0;
16179     char_u	*p;			/* position in buf */
16180     char_u	*start;			/* start of current line */
16181 
16182     if (argvars[1].v_type != VAR_UNKNOWN)
16183     {
16184 	if (STRCMP(get_tv_string(&argvars[1]), "b") == 0)
16185 	    binary = TRUE;
16186 	if (argvars[2].v_type != VAR_UNKNOWN)
16187 	    maxline = get_tv_number(&argvars[2]);
16188     }
16189 
16190     if (rettv_list_alloc(rettv) == FAIL)
16191 	return;
16192 
16193     /* Always open the file in binary mode, library functions have a mind of
16194      * their own about CR-LF conversion. */
16195     fname = get_tv_string(&argvars[0]);
16196     if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL)
16197     {
16198 	EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname);
16199 	return;
16200     }
16201 
16202     while (cnt < maxline || maxline < 0)
16203     {
16204 	readlen = (int)fread(buf, 1, io_size, fd);
16205 
16206 	/* This for loop processes what was read, but is also entered at end
16207 	 * of file so that either:
16208 	 * - an incomplete line gets written
16209 	 * - a "binary" file gets an empty line at the end if it ends in a
16210 	 *   newline.  */
16211 	for (p = buf, start = buf;
16212 		p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary));
16213 		++p)
16214 	{
16215 	    if (*p == '\n' || readlen <= 0)
16216 	    {
16217 		listitem_T  *li;
16218 		char_u	    *s	= NULL;
16219 		long_u	    len = p - start;
16220 
16221 		/* Finished a line.  Remove CRs before NL. */
16222 		if (readlen > 0 && !binary)
16223 		{
16224 		    while (len > 0 && start[len - 1] == '\r')
16225 			--len;
16226 		    /* removal may cross back to the "prev" string */
16227 		    if (len == 0)
16228 			while (prevlen > 0 && prev[prevlen - 1] == '\r')
16229 			    --prevlen;
16230 		}
16231 		if (prevlen == 0)
16232 		    s = vim_strnsave(start, (int)len);
16233 		else
16234 		{
16235 		    /* Change "prev" buffer to be the right size.  This way
16236 		     * the bytes are only copied once, and very long lines are
16237 		     * allocated only once.  */
16238 		    if ((s = vim_realloc(prev, prevlen + len + 1)) != NULL)
16239 		    {
16240 			mch_memmove(s + prevlen, start, len);
16241 			s[prevlen + len] = NUL;
16242 			prev = NULL; /* the list will own the string */
16243 			prevlen = prevsize = 0;
16244 		    }
16245 		}
16246 		if (s == NULL)
16247 		{
16248 		    do_outofmem_msg((long_u) prevlen + len + 1);
16249 		    failed = TRUE;
16250 		    break;
16251 		}
16252 
16253 		if ((li = listitem_alloc()) == NULL)
16254 		{
16255 		    vim_free(s);
16256 		    failed = TRUE;
16257 		    break;
16258 		}
16259 		li->li_tv.v_type = VAR_STRING;
16260 		li->li_tv.v_lock = 0;
16261 		li->li_tv.vval.v_string = s;
16262 		list_append(rettv->vval.v_list, li);
16263 
16264 		start = p + 1; /* step over newline */
16265 		if ((++cnt >= maxline && maxline >= 0) || readlen <= 0)
16266 		    break;
16267 	    }
16268 	    else if (*p == NUL)
16269 		*p = '\n';
16270 #ifdef FEAT_MBYTE
16271 	    /* Check for utf8 "bom"; U+FEFF is encoded as EF BB BF.  Do this
16272 	     * when finding the BF and check the previous two bytes. */
16273 	    else if (*p == 0xbf && enc_utf8 && !binary)
16274 	    {
16275 		/* Find the two bytes before the 0xbf.	If p is at buf, or buf
16276 		 * + 1, these may be in the "prev" string. */
16277 		char_u back1 = p >= buf + 1 ? p[-1]
16278 				     : prevlen >= 1 ? prev[prevlen - 1] : NUL;
16279 		char_u back2 = p >= buf + 2 ? p[-2]
16280 			  : p == buf + 1 && prevlen >= 1 ? prev[prevlen - 1]
16281 			  : prevlen >= 2 ? prev[prevlen - 2] : NUL;
16282 
16283 		if (back2 == 0xef && back1 == 0xbb)
16284 		{
16285 		    char_u *dest = p - 2;
16286 
16287 		    /* Usually a BOM is at the beginning of a file, and so at
16288 		     * the beginning of a line; then we can just step over it.
16289 		     */
16290 		    if (start == dest)
16291 			start = p + 1;
16292 		    else
16293 		    {
16294 			/* have to shuffle buf to close gap */
16295 			int adjust_prevlen = 0;
16296 
16297 			if (dest < buf)
16298 			{
16299 			    adjust_prevlen = (int)(buf - dest); /* must be 1 or 2 */
16300 			    dest = buf;
16301 			}
16302 			if (readlen > p - buf + 1)
16303 			    mch_memmove(dest, p + 1, readlen - (p - buf) - 1);
16304 			readlen -= 3 - adjust_prevlen;
16305 			prevlen -= adjust_prevlen;
16306 			p = dest - 1;
16307 		    }
16308 		}
16309 	    }
16310 #endif
16311 	} /* for */
16312 
16313 	if (failed || (cnt >= maxline && maxline >= 0) || readlen <= 0)
16314 	    break;
16315 	if (start < p)
16316 	{
16317 	    /* There's part of a line in buf, store it in "prev". */
16318 	    if (p - start + prevlen >= prevsize)
16319 	    {
16320 		/* need bigger "prev" buffer */
16321 		char_u *newprev;
16322 
16323 		/* A common use case is ordinary text files and "prev" gets a
16324 		 * fragment of a line, so the first allocation is made
16325 		 * small, to avoid repeatedly 'allocing' large and
16326 		 * 'reallocing' small. */
16327 		if (prevsize == 0)
16328 		    prevsize = (long)(p - start);
16329 		else
16330 		{
16331 		    long grow50pc = (prevsize * 3) / 2;
16332 		    long growmin  = (long)((p - start) * 2 + prevlen);
16333 		    prevsize = grow50pc > growmin ? grow50pc : growmin;
16334 		}
16335 		newprev = prev == NULL ? alloc(prevsize)
16336 						: vim_realloc(prev, prevsize);
16337 		if (newprev == NULL)
16338 		{
16339 		    do_outofmem_msg((long_u)prevsize);
16340 		    failed = TRUE;
16341 		    break;
16342 		}
16343 		prev = newprev;
16344 	    }
16345 	    /* Add the line part to end of "prev". */
16346 	    mch_memmove(prev + prevlen, start, p - start);
16347 	    prevlen += (long)(p - start);
16348 	}
16349     } /* while */
16350 
16351     /*
16352      * For a negative line count use only the lines at the end of the file,
16353      * free the rest.
16354      */
16355     if (!failed && maxline < 0)
16356 	while (cnt > -maxline)
16357 	{
16358 	    listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first);
16359 	    --cnt;
16360 	}
16361 
16362     if (failed)
16363     {
16364 	list_free(rettv->vval.v_list, TRUE);
16365 	/* readfile doc says an empty list is returned on error */
16366 	rettv->vval.v_list = list_alloc();
16367     }
16368 
16369     vim_free(prev);
16370     fclose(fd);
16371 }
16372 
16373 #if defined(FEAT_RELTIME)
16374 static int list2proftime(typval_T *arg, proftime_T *tm);
16375 
16376 /*
16377  * Convert a List to proftime_T.
16378  * Return FAIL when there is something wrong.
16379  */
16380     static int
16381 list2proftime(typval_T *arg, proftime_T *tm)
16382 {
16383     long	n1, n2;
16384     int	error = FALSE;
16385 
16386     if (arg->v_type != VAR_LIST || arg->vval.v_list == NULL
16387 					     || arg->vval.v_list->lv_len != 2)
16388 	return FAIL;
16389     n1 = list_find_nr(arg->vval.v_list, 0L, &error);
16390     n2 = list_find_nr(arg->vval.v_list, 1L, &error);
16391 # ifdef WIN3264
16392     tm->HighPart = n1;
16393     tm->LowPart = n2;
16394 # else
16395     tm->tv_sec = n1;
16396     tm->tv_usec = n2;
16397 # endif
16398     return error ? FAIL : OK;
16399 }
16400 #endif /* FEAT_RELTIME */
16401 
16402 /*
16403  * "reltime()" function
16404  */
16405     static void
16406 f_reltime(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
16407 {
16408 #ifdef FEAT_RELTIME
16409     proftime_T	res;
16410     proftime_T	start;
16411 
16412     if (argvars[0].v_type == VAR_UNKNOWN)
16413     {
16414 	/* No arguments: get current time. */
16415 	profile_start(&res);
16416     }
16417     else if (argvars[1].v_type == VAR_UNKNOWN)
16418     {
16419 	if (list2proftime(&argvars[0], &res) == FAIL)
16420 	    return;
16421 	profile_end(&res);
16422     }
16423     else
16424     {
16425 	/* Two arguments: compute the difference. */
16426 	if (list2proftime(&argvars[0], &start) == FAIL
16427 		|| list2proftime(&argvars[1], &res) == FAIL)
16428 	    return;
16429 	profile_sub(&res, &start);
16430     }
16431 
16432     if (rettv_list_alloc(rettv) == OK)
16433     {
16434 	long	n1, n2;
16435 
16436 # ifdef WIN3264
16437 	n1 = res.HighPart;
16438 	n2 = res.LowPart;
16439 # else
16440 	n1 = res.tv_sec;
16441 	n2 = res.tv_usec;
16442 # endif
16443 	list_append_number(rettv->vval.v_list, (varnumber_T)n1);
16444 	list_append_number(rettv->vval.v_list, (varnumber_T)n2);
16445     }
16446 #endif
16447 }
16448 
16449 #ifdef FEAT_FLOAT
16450 /*
16451  * "reltimefloat()" function
16452  */
16453     static void
16454 f_reltimefloat(typval_T *argvars UNUSED, typval_T *rettv)
16455 {
16456 # ifdef FEAT_RELTIME
16457     proftime_T	tm;
16458 # endif
16459 
16460     rettv->v_type = VAR_FLOAT;
16461     rettv->vval.v_float = 0;
16462 # ifdef FEAT_RELTIME
16463     if (list2proftime(&argvars[0], &tm) == OK)
16464 	rettv->vval.v_float = profile_float(&tm);
16465 # endif
16466 }
16467 #endif
16468 
16469 /*
16470  * "reltimestr()" function
16471  */
16472     static void
16473 f_reltimestr(typval_T *argvars UNUSED, typval_T *rettv)
16474 {
16475 #ifdef FEAT_RELTIME
16476     proftime_T	tm;
16477 #endif
16478 
16479     rettv->v_type = VAR_STRING;
16480     rettv->vval.v_string = NULL;
16481 #ifdef FEAT_RELTIME
16482     if (list2proftime(&argvars[0], &tm) == OK)
16483 	rettv->vval.v_string = vim_strsave((char_u *)profile_msg(&tm));
16484 #endif
16485 }
16486 
16487 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
16488 static void make_connection(void);
16489 static int check_connection(void);
16490 
16491     static void
16492 make_connection(void)
16493 {
16494     if (X_DISPLAY == NULL
16495 # ifdef FEAT_GUI
16496 	    && !gui.in_use
16497 # endif
16498 	    )
16499     {
16500 	x_force_connect = TRUE;
16501 	setup_term_clip();
16502 	x_force_connect = FALSE;
16503     }
16504 }
16505 
16506     static int
16507 check_connection(void)
16508 {
16509     make_connection();
16510     if (X_DISPLAY == NULL)
16511     {
16512 	EMSG(_("E240: No connection to Vim server"));
16513 	return FAIL;
16514     }
16515     return OK;
16516 }
16517 #endif
16518 
16519 #ifdef FEAT_CLIENTSERVER
16520 static void remote_common(typval_T *argvars, typval_T *rettv, int expr);
16521 
16522     static void
16523 remote_common(typval_T *argvars, typval_T *rettv, int expr)
16524 {
16525     char_u	*server_name;
16526     char_u	*keys;
16527     char_u	*r = NULL;
16528     char_u	buf[NUMBUFLEN];
16529 # ifdef WIN32
16530     HWND	w;
16531 # else
16532     Window	w;
16533 # endif
16534 
16535     if (check_restricted() || check_secure())
16536 	return;
16537 
16538 # ifdef FEAT_X11
16539     if (check_connection() == FAIL)
16540 	return;
16541 # endif
16542 
16543     server_name = get_tv_string_chk(&argvars[0]);
16544     if (server_name == NULL)
16545 	return;		/* type error; errmsg already given */
16546     keys = get_tv_string_buf(&argvars[1], buf);
16547 # ifdef WIN32
16548     if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0)
16549 # else
16550     if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE)
16551 									  < 0)
16552 # endif
16553     {
16554 	if (r != NULL)
16555 	    EMSG(r);		/* sending worked but evaluation failed */
16556 	else
16557 	    EMSG2(_("E241: Unable to send to %s"), server_name);
16558 	return;
16559     }
16560 
16561     rettv->vval.v_string = r;
16562 
16563     if (argvars[2].v_type != VAR_UNKNOWN)
16564     {
16565 	dictitem_T	v;
16566 	char_u		str[30];
16567 	char_u		*idvar;
16568 
16569 	sprintf((char *)str, PRINTF_HEX_LONG_U, (long_u)w);
16570 	v.di_tv.v_type = VAR_STRING;
16571 	v.di_tv.vval.v_string = vim_strsave(str);
16572 	idvar = get_tv_string_chk(&argvars[2]);
16573 	if (idvar != NULL)
16574 	    set_var(idvar, &v.di_tv, FALSE);
16575 	vim_free(v.di_tv.vval.v_string);
16576     }
16577 }
16578 #endif
16579 
16580 /*
16581  * "remote_expr()" function
16582  */
16583     static void
16584 f_remote_expr(typval_T *argvars UNUSED, typval_T *rettv)
16585 {
16586     rettv->v_type = VAR_STRING;
16587     rettv->vval.v_string = NULL;
16588 #ifdef FEAT_CLIENTSERVER
16589     remote_common(argvars, rettv, TRUE);
16590 #endif
16591 }
16592 
16593 /*
16594  * "remote_foreground()" function
16595  */
16596     static void
16597 f_remote_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
16598 {
16599 #ifdef FEAT_CLIENTSERVER
16600 # ifdef WIN32
16601     /* On Win32 it's done in this application. */
16602     {
16603 	char_u	*server_name = get_tv_string_chk(&argvars[0]);
16604 
16605 	if (server_name != NULL)
16606 	    serverForeground(server_name);
16607     }
16608 # else
16609     /* Send a foreground() expression to the server. */
16610     argvars[1].v_type = VAR_STRING;
16611     argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()");
16612     argvars[2].v_type = VAR_UNKNOWN;
16613     remote_common(argvars, rettv, TRUE);
16614     vim_free(argvars[1].vval.v_string);
16615 # endif
16616 #endif
16617 }
16618 
16619     static void
16620 f_remote_peek(typval_T *argvars UNUSED, typval_T *rettv)
16621 {
16622 #ifdef FEAT_CLIENTSERVER
16623     dictitem_T	v;
16624     char_u	*s = NULL;
16625 # ifdef WIN32
16626     long_u	n = 0;
16627 # endif
16628     char_u	*serverid;
16629 
16630     if (check_restricted() || check_secure())
16631     {
16632 	rettv->vval.v_number = -1;
16633 	return;
16634     }
16635     serverid = get_tv_string_chk(&argvars[0]);
16636     if (serverid == NULL)
16637     {
16638 	rettv->vval.v_number = -1;
16639 	return;		/* type error; errmsg already given */
16640     }
16641 # ifdef WIN32
16642     sscanf((const char *)serverid, SCANF_HEX_LONG_U, &n);
16643     if (n == 0)
16644 	rettv->vval.v_number = -1;
16645     else
16646     {
16647 	s = serverGetReply((HWND)n, FALSE, FALSE, FALSE);
16648 	rettv->vval.v_number = (s != NULL);
16649     }
16650 # else
16651     if (check_connection() == FAIL)
16652 	return;
16653 
16654     rettv->vval.v_number = serverPeekReply(X_DISPLAY,
16655 						serverStrToWin(serverid), &s);
16656 # endif
16657 
16658     if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0)
16659     {
16660 	char_u		*retvar;
16661 
16662 	v.di_tv.v_type = VAR_STRING;
16663 	v.di_tv.vval.v_string = vim_strsave(s);
16664 	retvar = get_tv_string_chk(&argvars[1]);
16665 	if (retvar != NULL)
16666 	    set_var(retvar, &v.di_tv, FALSE);
16667 	vim_free(v.di_tv.vval.v_string);
16668     }
16669 #else
16670     rettv->vval.v_number = -1;
16671 #endif
16672 }
16673 
16674     static void
16675 f_remote_read(typval_T *argvars UNUSED, typval_T *rettv)
16676 {
16677     char_u	*r = NULL;
16678 
16679 #ifdef FEAT_CLIENTSERVER
16680     char_u	*serverid = get_tv_string_chk(&argvars[0]);
16681 
16682     if (serverid != NULL && !check_restricted() && !check_secure())
16683     {
16684 # ifdef WIN32
16685 	/* The server's HWND is encoded in the 'id' parameter */
16686 	long_u		n = 0;
16687 
16688 	sscanf((char *)serverid, SCANF_HEX_LONG_U, &n);
16689 	if (n != 0)
16690 	    r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
16691 	if (r == NULL)
16692 # else
16693 	if (check_connection() == FAIL || serverReadReply(X_DISPLAY,
16694 		serverStrToWin(serverid), &r, FALSE) < 0)
16695 # endif
16696 	    EMSG(_("E277: Unable to read a server reply"));
16697     }
16698 #endif
16699     rettv->v_type = VAR_STRING;
16700     rettv->vval.v_string = r;
16701 }
16702 
16703 /*
16704  * "remote_send()" function
16705  */
16706     static void
16707 f_remote_send(typval_T *argvars UNUSED, typval_T *rettv)
16708 {
16709     rettv->v_type = VAR_STRING;
16710     rettv->vval.v_string = NULL;
16711 #ifdef FEAT_CLIENTSERVER
16712     remote_common(argvars, rettv, FALSE);
16713 #endif
16714 }
16715 
16716 /*
16717  * "remove()" function
16718  */
16719     static void
16720 f_remove(typval_T *argvars, typval_T *rettv)
16721 {
16722     list_T	*l;
16723     listitem_T	*item, *item2;
16724     listitem_T	*li;
16725     long	idx;
16726     long	end;
16727     char_u	*key;
16728     dict_T	*d;
16729     dictitem_T	*di;
16730     char_u	*arg_errmsg = (char_u *)N_("remove() argument");
16731 
16732     if (argvars[0].v_type == VAR_DICT)
16733     {
16734 	if (argvars[2].v_type != VAR_UNKNOWN)
16735 	    EMSG2(_(e_toomanyarg), "remove()");
16736 	else if ((d = argvars[0].vval.v_dict) != NULL
16737 		&& !tv_check_lock(d->dv_lock, arg_errmsg, TRUE))
16738 	{
16739 	    key = get_tv_string_chk(&argvars[1]);
16740 	    if (key != NULL)
16741 	    {
16742 		di = dict_find(d, key, -1);
16743 		if (di == NULL)
16744 		    EMSG2(_(e_dictkey), key);
16745 		else if (!var_check_fixed(di->di_flags, arg_errmsg, TRUE)
16746 			    && !var_check_ro(di->di_flags, arg_errmsg, TRUE))
16747 		{
16748 		    *rettv = di->di_tv;
16749 		    init_tv(&di->di_tv);
16750 		    dictitem_remove(d, di);
16751 		}
16752 	    }
16753 	}
16754     }
16755     else if (argvars[0].v_type != VAR_LIST)
16756 	EMSG2(_(e_listdictarg), "remove()");
16757     else if ((l = argvars[0].vval.v_list) != NULL
16758 	    && !tv_check_lock(l->lv_lock, arg_errmsg, TRUE))
16759     {
16760 	int	    error = FALSE;
16761 
16762 	idx = get_tv_number_chk(&argvars[1], &error);
16763 	if (error)
16764 	    ;		/* type error: do nothing, errmsg already given */
16765 	else if ((item = list_find(l, idx)) == NULL)
16766 	    EMSGN(_(e_listidx), idx);
16767 	else
16768 	{
16769 	    if (argvars[2].v_type == VAR_UNKNOWN)
16770 	    {
16771 		/* Remove one item, return its value. */
16772 		vimlist_remove(l, item, item);
16773 		*rettv = item->li_tv;
16774 		vim_free(item);
16775 	    }
16776 	    else
16777 	    {
16778 		/* Remove range of items, return list with values. */
16779 		end = get_tv_number_chk(&argvars[2], &error);
16780 		if (error)
16781 		    ;		/* type error: do nothing */
16782 		else if ((item2 = list_find(l, end)) == NULL)
16783 		    EMSGN(_(e_listidx), end);
16784 		else
16785 		{
16786 		    int	    cnt = 0;
16787 
16788 		    for (li = item; li != NULL; li = li->li_next)
16789 		    {
16790 			++cnt;
16791 			if (li == item2)
16792 			    break;
16793 		    }
16794 		    if (li == NULL)  /* didn't find "item2" after "item" */
16795 			EMSG(_(e_invrange));
16796 		    else
16797 		    {
16798 			vimlist_remove(l, item, item2);
16799 			if (rettv_list_alloc(rettv) == OK)
16800 			{
16801 			    l = rettv->vval.v_list;
16802 			    l->lv_first = item;
16803 			    l->lv_last = item2;
16804 			    item->li_prev = NULL;
16805 			    item2->li_next = NULL;
16806 			    l->lv_len = cnt;
16807 			}
16808 		    }
16809 		}
16810 	    }
16811 	}
16812     }
16813 }
16814 
16815 /*
16816  * "rename({from}, {to})" function
16817  */
16818     static void
16819 f_rename(typval_T *argvars, typval_T *rettv)
16820 {
16821     char_u	buf[NUMBUFLEN];
16822 
16823     if (check_restricted() || check_secure())
16824 	rettv->vval.v_number = -1;
16825     else
16826 	rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]),
16827 				      get_tv_string_buf(&argvars[1], buf));
16828 }
16829 
16830 /*
16831  * "repeat()" function
16832  */
16833     static void
16834 f_repeat(typval_T *argvars, typval_T *rettv)
16835 {
16836     char_u	*p;
16837     int		n;
16838     int		slen;
16839     int		len;
16840     char_u	*r;
16841     int		i;
16842 
16843     n = get_tv_number(&argvars[1]);
16844     if (argvars[0].v_type == VAR_LIST)
16845     {
16846 	if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL)
16847 	    while (n-- > 0)
16848 		if (list_extend(rettv->vval.v_list,
16849 					argvars[0].vval.v_list, NULL) == FAIL)
16850 		    break;
16851     }
16852     else
16853     {
16854 	p = get_tv_string(&argvars[0]);
16855 	rettv->v_type = VAR_STRING;
16856 	rettv->vval.v_string = NULL;
16857 
16858 	slen = (int)STRLEN(p);
16859 	len = slen * n;
16860 	if (len <= 0)
16861 	    return;
16862 
16863 	r = alloc(len + 1);
16864 	if (r != NULL)
16865 	{
16866 	    for (i = 0; i < n; i++)
16867 		mch_memmove(r + i * slen, p, (size_t)slen);
16868 	    r[len] = NUL;
16869 	}
16870 
16871 	rettv->vval.v_string = r;
16872     }
16873 }
16874 
16875 /*
16876  * "resolve()" function
16877  */
16878     static void
16879 f_resolve(typval_T *argvars, typval_T *rettv)
16880 {
16881     char_u	*p;
16882 #ifdef HAVE_READLINK
16883     char_u	*buf = NULL;
16884 #endif
16885 
16886     p = get_tv_string(&argvars[0]);
16887 #ifdef FEAT_SHORTCUT
16888     {
16889 	char_u	*v = NULL;
16890 
16891 	v = mch_resolve_shortcut(p);
16892 	if (v != NULL)
16893 	    rettv->vval.v_string = v;
16894 	else
16895 	    rettv->vval.v_string = vim_strsave(p);
16896     }
16897 #else
16898 # ifdef HAVE_READLINK
16899     {
16900 	char_u	*cpy;
16901 	int	len;
16902 	char_u	*remain = NULL;
16903 	char_u	*q;
16904 	int	is_relative_to_current = FALSE;
16905 	int	has_trailing_pathsep = FALSE;
16906 	int	limit = 100;
16907 
16908 	p = vim_strsave(p);
16909 
16910 	if (p[0] == '.' && (vim_ispathsep(p[1])
16911 				   || (p[1] == '.' && (vim_ispathsep(p[2])))))
16912 	    is_relative_to_current = TRUE;
16913 
16914 	len = STRLEN(p);
16915 	if (len > 0 && after_pathsep(p, p + len))
16916 	{
16917 	    has_trailing_pathsep = TRUE;
16918 	    p[len - 1] = NUL; /* the trailing slash breaks readlink() */
16919 	}
16920 
16921 	q = getnextcomp(p);
16922 	if (*q != NUL)
16923 	{
16924 	    /* Separate the first path component in "p", and keep the
16925 	     * remainder (beginning with the path separator). */
16926 	    remain = vim_strsave(q - 1);
16927 	    q[-1] = NUL;
16928 	}
16929 
16930 	buf = alloc(MAXPATHL + 1);
16931 	if (buf == NULL)
16932 	    goto fail;
16933 
16934 	for (;;)
16935 	{
16936 	    for (;;)
16937 	    {
16938 		len = readlink((char *)p, (char *)buf, MAXPATHL);
16939 		if (len <= 0)
16940 		    break;
16941 		buf[len] = NUL;
16942 
16943 		if (limit-- == 0)
16944 		{
16945 		    vim_free(p);
16946 		    vim_free(remain);
16947 		    EMSG(_("E655: Too many symbolic links (cycle?)"));
16948 		    rettv->vval.v_string = NULL;
16949 		    goto fail;
16950 		}
16951 
16952 		/* Ensure that the result will have a trailing path separator
16953 		 * if the argument has one. */
16954 		if (remain == NULL && has_trailing_pathsep)
16955 		    add_pathsep(buf);
16956 
16957 		/* Separate the first path component in the link value and
16958 		 * concatenate the remainders. */
16959 		q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf);
16960 		if (*q != NUL)
16961 		{
16962 		    if (remain == NULL)
16963 			remain = vim_strsave(q - 1);
16964 		    else
16965 		    {
16966 			cpy = concat_str(q - 1, remain);
16967 			if (cpy != NULL)
16968 			{
16969 			    vim_free(remain);
16970 			    remain = cpy;
16971 			}
16972 		    }
16973 		    q[-1] = NUL;
16974 		}
16975 
16976 		q = gettail(p);
16977 		if (q > p && *q == NUL)
16978 		{
16979 		    /* Ignore trailing path separator. */
16980 		    q[-1] = NUL;
16981 		    q = gettail(p);
16982 		}
16983 		if (q > p && !mch_isFullName(buf))
16984 		{
16985 		    /* symlink is relative to directory of argument */
16986 		    cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
16987 		    if (cpy != NULL)
16988 		    {
16989 			STRCPY(cpy, p);
16990 			STRCPY(gettail(cpy), buf);
16991 			vim_free(p);
16992 			p = cpy;
16993 		    }
16994 		}
16995 		else
16996 		{
16997 		    vim_free(p);
16998 		    p = vim_strsave(buf);
16999 		}
17000 	    }
17001 
17002 	    if (remain == NULL)
17003 		break;
17004 
17005 	    /* Append the first path component of "remain" to "p". */
17006 	    q = getnextcomp(remain + 1);
17007 	    len = q - remain - (*q != NUL);
17008 	    cpy = vim_strnsave(p, STRLEN(p) + len);
17009 	    if (cpy != NULL)
17010 	    {
17011 		STRNCAT(cpy, remain, len);
17012 		vim_free(p);
17013 		p = cpy;
17014 	    }
17015 	    /* Shorten "remain". */
17016 	    if (*q != NUL)
17017 		STRMOVE(remain, q - 1);
17018 	    else
17019 	    {
17020 		vim_free(remain);
17021 		remain = NULL;
17022 	    }
17023 	}
17024 
17025 	/* If the result is a relative path name, make it explicitly relative to
17026 	 * the current directory if and only if the argument had this form. */
17027 	if (!vim_ispathsep(*p))
17028 	{
17029 	    if (is_relative_to_current
17030 		    && *p != NUL
17031 		    && !(p[0] == '.'
17032 			&& (p[1] == NUL
17033 			    || vim_ispathsep(p[1])
17034 			    || (p[1] == '.'
17035 				&& (p[2] == NUL
17036 				    || vim_ispathsep(p[2]))))))
17037 	    {
17038 		/* Prepend "./". */
17039 		cpy = concat_str((char_u *)"./", p);
17040 		if (cpy != NULL)
17041 		{
17042 		    vim_free(p);
17043 		    p = cpy;
17044 		}
17045 	    }
17046 	    else if (!is_relative_to_current)
17047 	    {
17048 		/* Strip leading "./". */
17049 		q = p;
17050 		while (q[0] == '.' && vim_ispathsep(q[1]))
17051 		    q += 2;
17052 		if (q > p)
17053 		    STRMOVE(p, p + 2);
17054 	    }
17055 	}
17056 
17057 	/* Ensure that the result will have no trailing path separator
17058 	 * if the argument had none.  But keep "/" or "//". */
17059 	if (!has_trailing_pathsep)
17060 	{
17061 	    q = p + STRLEN(p);
17062 	    if (after_pathsep(p, q))
17063 		*gettail_sep(p) = NUL;
17064 	}
17065 
17066 	rettv->vval.v_string = p;
17067     }
17068 # else
17069     rettv->vval.v_string = vim_strsave(p);
17070 # endif
17071 #endif
17072 
17073     simplify_filename(rettv->vval.v_string);
17074 
17075 #ifdef HAVE_READLINK
17076 fail:
17077     vim_free(buf);
17078 #endif
17079     rettv->v_type = VAR_STRING;
17080 }
17081 
17082 /*
17083  * "reverse({list})" function
17084  */
17085     static void
17086 f_reverse(typval_T *argvars, typval_T *rettv)
17087 {
17088     list_T	*l;
17089     listitem_T	*li, *ni;
17090 
17091     if (argvars[0].v_type != VAR_LIST)
17092 	EMSG2(_(e_listarg), "reverse()");
17093     else if ((l = argvars[0].vval.v_list) != NULL
17094 	    && !tv_check_lock(l->lv_lock,
17095 				    (char_u *)N_("reverse() argument"), TRUE))
17096     {
17097 	li = l->lv_last;
17098 	l->lv_first = l->lv_last = NULL;
17099 	l->lv_len = 0;
17100 	while (li != NULL)
17101 	{
17102 	    ni = li->li_prev;
17103 	    list_append(l, li);
17104 	    li = ni;
17105 	}
17106 	rettv->vval.v_list = l;
17107 	rettv->v_type = VAR_LIST;
17108 	++l->lv_refcount;
17109 	l->lv_idx = l->lv_len - l->lv_idx - 1;
17110     }
17111 }
17112 
17113 #define SP_NOMOVE	0x01	    /* don't move cursor */
17114 #define SP_REPEAT	0x02	    /* repeat to find outer pair */
17115 #define SP_RETCOUNT	0x04	    /* return matchcount */
17116 #define SP_SETPCMARK	0x08	    /* set previous context mark */
17117 #define SP_START	0x10	    /* accept match at start position */
17118 #define SP_SUBPAT	0x20	    /* return nr of matching sub-pattern */
17119 #define SP_END		0x40	    /* leave cursor at end of match */
17120 #define SP_COLUMN	0x80	    /* start at cursor column */
17121 
17122 static int get_search_arg(typval_T *varp, int *flagsp);
17123 
17124 /*
17125  * Get flags for a search function.
17126  * Possibly sets "p_ws".
17127  * Returns BACKWARD, FORWARD or zero (for an error).
17128  */
17129     static int
17130 get_search_arg(typval_T *varp, int *flagsp)
17131 {
17132     int		dir = FORWARD;
17133     char_u	*flags;
17134     char_u	nbuf[NUMBUFLEN];
17135     int		mask;
17136 
17137     if (varp->v_type != VAR_UNKNOWN)
17138     {
17139 	flags = get_tv_string_buf_chk(varp, nbuf);
17140 	if (flags == NULL)
17141 	    return 0;		/* type error; errmsg already given */
17142 	while (*flags != NUL)
17143 	{
17144 	    switch (*flags)
17145 	    {
17146 		case 'b': dir = BACKWARD; break;
17147 		case 'w': p_ws = TRUE; break;
17148 		case 'W': p_ws = FALSE; break;
17149 		default:  mask = 0;
17150 			  if (flagsp != NULL)
17151 			     switch (*flags)
17152 			     {
17153 				 case 'c': mask = SP_START; break;
17154 				 case 'e': mask = SP_END; break;
17155 				 case 'm': mask = SP_RETCOUNT; break;
17156 				 case 'n': mask = SP_NOMOVE; break;
17157 				 case 'p': mask = SP_SUBPAT; break;
17158 				 case 'r': mask = SP_REPEAT; break;
17159 				 case 's': mask = SP_SETPCMARK; break;
17160 				 case 'z': mask = SP_COLUMN; break;
17161 			     }
17162 			  if (mask == 0)
17163 			  {
17164 			      EMSG2(_(e_invarg2), flags);
17165 			      dir = 0;
17166 			  }
17167 			  else
17168 			      *flagsp |= mask;
17169 	    }
17170 	    if (dir == 0)
17171 		break;
17172 	    ++flags;
17173 	}
17174     }
17175     return dir;
17176 }
17177 
17178 /*
17179  * Shared by search() and searchpos() functions.
17180  */
17181     static int
17182 search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
17183 {
17184     int		flags;
17185     char_u	*pat;
17186     pos_T	pos;
17187     pos_T	save_cursor;
17188     int		save_p_ws = p_ws;
17189     int		dir;
17190     int		retval = 0;	/* default: FAIL */
17191     long	lnum_stop = 0;
17192     proftime_T	tm;
17193 #ifdef FEAT_RELTIME
17194     long	time_limit = 0;
17195 #endif
17196     int		options = SEARCH_KEEP;
17197     int		subpatnum;
17198 
17199     pat = get_tv_string(&argvars[0]);
17200     dir = get_search_arg(&argvars[1], flagsp);	/* may set p_ws */
17201     if (dir == 0)
17202 	goto theend;
17203     flags = *flagsp;
17204     if (flags & SP_START)
17205 	options |= SEARCH_START;
17206     if (flags & SP_END)
17207 	options |= SEARCH_END;
17208     if (flags & SP_COLUMN)
17209 	options |= SEARCH_COL;
17210 
17211     /* Optional arguments: line number to stop searching and timeout. */
17212     if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)
17213     {
17214 	lnum_stop = get_tv_number_chk(&argvars[2], NULL);
17215 	if (lnum_stop < 0)
17216 	    goto theend;
17217 #ifdef FEAT_RELTIME
17218 	if (argvars[3].v_type != VAR_UNKNOWN)
17219 	{
17220 	    time_limit = get_tv_number_chk(&argvars[3], NULL);
17221 	    if (time_limit < 0)
17222 		goto theend;
17223 	}
17224 #endif
17225     }
17226 
17227 #ifdef FEAT_RELTIME
17228     /* Set the time limit, if there is one. */
17229     profile_setlimit(time_limit, &tm);
17230 #endif
17231 
17232     /*
17233      * This function does not accept SP_REPEAT and SP_RETCOUNT flags.
17234      * Check to make sure only those flags are set.
17235      * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both
17236      * flags cannot be set. Check for that condition also.
17237      */
17238     if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0)
17239 	    || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)))
17240     {
17241 	EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
17242 	goto theend;
17243     }
17244 
17245     pos = save_cursor = curwin->w_cursor;
17246     subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
17247 				options, RE_SEARCH, (linenr_T)lnum_stop, &tm);
17248     if (subpatnum != FAIL)
17249     {
17250 	if (flags & SP_SUBPAT)
17251 	    retval = subpatnum;
17252 	else
17253 	    retval = pos.lnum;
17254 	if (flags & SP_SETPCMARK)
17255 	    setpcmark();
17256 	curwin->w_cursor = pos;
17257 	if (match_pos != NULL)
17258 	{
17259 	    /* Store the match cursor position */
17260 	    match_pos->lnum = pos.lnum;
17261 	    match_pos->col = pos.col + 1;
17262 	}
17263 	/* "/$" will put the cursor after the end of the line, may need to
17264 	 * correct that here */
17265 	check_cursor();
17266     }
17267 
17268     /* If 'n' flag is used: restore cursor position. */
17269     if (flags & SP_NOMOVE)
17270 	curwin->w_cursor = save_cursor;
17271     else
17272 	curwin->w_set_curswant = TRUE;
17273 theend:
17274     p_ws = save_p_ws;
17275 
17276     return retval;
17277 }
17278 
17279 #ifdef FEAT_FLOAT
17280 
17281 /*
17282  * round() is not in C90, use ceil() or floor() instead.
17283  */
17284     float_T
17285 vim_round(float_T f)
17286 {
17287     return f > 0 ? floor(f + 0.5) : ceil(f - 0.5);
17288 }
17289 
17290 /*
17291  * "round({float})" function
17292  */
17293     static void
17294 f_round(typval_T *argvars, typval_T *rettv)
17295 {
17296     float_T	f = 0.0;
17297 
17298     rettv->v_type = VAR_FLOAT;
17299     if (get_float_arg(argvars, &f) == OK)
17300 	rettv->vval.v_float = vim_round(f);
17301     else
17302 	rettv->vval.v_float = 0.0;
17303 }
17304 #endif
17305 
17306 /*
17307  * "screenattr()" function
17308  */
17309     static void
17310 f_screenattr(typval_T *argvars, typval_T *rettv)
17311 {
17312     int		row;
17313     int		col;
17314     int		c;
17315 
17316     row = get_tv_number_chk(&argvars[0], NULL) - 1;
17317     col = get_tv_number_chk(&argvars[1], NULL) - 1;
17318     if (row < 0 || row >= screen_Rows
17319 	    || col < 0 || col >= screen_Columns)
17320 	c = -1;
17321     else
17322 	c = ScreenAttrs[LineOffset[row] + col];
17323     rettv->vval.v_number = c;
17324 }
17325 
17326 /*
17327  * "screenchar()" function
17328  */
17329     static void
17330 f_screenchar(typval_T *argvars, typval_T *rettv)
17331 {
17332     int		row;
17333     int		col;
17334     int		off;
17335     int		c;
17336 
17337     row = get_tv_number_chk(&argvars[0], NULL) - 1;
17338     col = get_tv_number_chk(&argvars[1], NULL) - 1;
17339     if (row < 0 || row >= screen_Rows
17340 	    || col < 0 || col >= screen_Columns)
17341 	c = -1;
17342     else
17343     {
17344 	off = LineOffset[row] + col;
17345 #ifdef FEAT_MBYTE
17346 	if (enc_utf8 && ScreenLinesUC[off] != 0)
17347 	    c = ScreenLinesUC[off];
17348 	else
17349 #endif
17350 	    c = ScreenLines[off];
17351     }
17352     rettv->vval.v_number = c;
17353 }
17354 
17355 /*
17356  * "screencol()" function
17357  *
17358  * First column is 1 to be consistent with virtcol().
17359  */
17360     static void
17361 f_screencol(typval_T *argvars UNUSED, typval_T *rettv)
17362 {
17363     rettv->vval.v_number = screen_screencol() + 1;
17364 }
17365 
17366 /*
17367  * "screenrow()" function
17368  */
17369     static void
17370 f_screenrow(typval_T *argvars UNUSED, typval_T *rettv)
17371 {
17372     rettv->vval.v_number = screen_screenrow() + 1;
17373 }
17374 
17375 /*
17376  * "search()" function
17377  */
17378     static void
17379 f_search(typval_T *argvars, typval_T *rettv)
17380 {
17381     int		flags = 0;
17382 
17383     rettv->vval.v_number = search_cmn(argvars, NULL, &flags);
17384 }
17385 
17386 /*
17387  * "searchdecl()" function
17388  */
17389     static void
17390 f_searchdecl(typval_T *argvars, typval_T *rettv)
17391 {
17392     int		locally = 1;
17393     int		thisblock = 0;
17394     int		error = FALSE;
17395     char_u	*name;
17396 
17397     rettv->vval.v_number = 1;	/* default: FAIL */
17398 
17399     name = get_tv_string_chk(&argvars[0]);
17400     if (argvars[1].v_type != VAR_UNKNOWN)
17401     {
17402 	locally = get_tv_number_chk(&argvars[1], &error) == 0;
17403 	if (!error && argvars[2].v_type != VAR_UNKNOWN)
17404 	    thisblock = get_tv_number_chk(&argvars[2], &error) != 0;
17405     }
17406     if (!error && name != NULL)
17407 	rettv->vval.v_number = find_decl(name, (int)STRLEN(name),
17408 				     locally, thisblock, SEARCH_KEEP) == FAIL;
17409 }
17410 
17411 /*
17412  * Used by searchpair() and searchpairpos()
17413  */
17414     static int
17415 searchpair_cmn(typval_T *argvars, pos_T *match_pos)
17416 {
17417     char_u	*spat, *mpat, *epat;
17418     char_u	*skip;
17419     int		save_p_ws = p_ws;
17420     int		dir;
17421     int		flags = 0;
17422     char_u	nbuf1[NUMBUFLEN];
17423     char_u	nbuf2[NUMBUFLEN];
17424     char_u	nbuf3[NUMBUFLEN];
17425     int		retval = 0;		/* default: FAIL */
17426     long	lnum_stop = 0;
17427     long	time_limit = 0;
17428 
17429     /* Get the three pattern arguments: start, middle, end. */
17430     spat = get_tv_string_chk(&argvars[0]);
17431     mpat = get_tv_string_buf_chk(&argvars[1], nbuf1);
17432     epat = get_tv_string_buf_chk(&argvars[2], nbuf2);
17433     if (spat == NULL || mpat == NULL || epat == NULL)
17434 	goto theend;	    /* type error */
17435 
17436     /* Handle the optional fourth argument: flags */
17437     dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
17438     if (dir == 0)
17439 	goto theend;
17440 
17441     /* Don't accept SP_END or SP_SUBPAT.
17442      * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set.
17443      */
17444     if ((flags & (SP_END | SP_SUBPAT)) != 0
17445 	    || ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)))
17446     {
17447 	EMSG2(_(e_invarg2), get_tv_string(&argvars[3]));
17448 	goto theend;
17449     }
17450 
17451     /* Using 'r' implies 'W', otherwise it doesn't work. */
17452     if (flags & SP_REPEAT)
17453 	p_ws = FALSE;
17454 
17455     /* Optional fifth argument: skip expression */
17456     if (argvars[3].v_type == VAR_UNKNOWN
17457 	    || argvars[4].v_type == VAR_UNKNOWN)
17458 	skip = (char_u *)"";
17459     else
17460     {
17461 	skip = get_tv_string_buf_chk(&argvars[4], nbuf3);
17462 	if (argvars[5].v_type != VAR_UNKNOWN)
17463 	{
17464 	    lnum_stop = get_tv_number_chk(&argvars[5], NULL);
17465 	    if (lnum_stop < 0)
17466 		goto theend;
17467 #ifdef FEAT_RELTIME
17468 	    if (argvars[6].v_type != VAR_UNKNOWN)
17469 	    {
17470 		time_limit = get_tv_number_chk(&argvars[6], NULL);
17471 		if (time_limit < 0)
17472 		    goto theend;
17473 	    }
17474 #endif
17475 	}
17476     }
17477     if (skip == NULL)
17478 	goto theend;	    /* type error */
17479 
17480     retval = do_searchpair(spat, mpat, epat, dir, skip, flags,
17481 					    match_pos, lnum_stop, time_limit);
17482 
17483 theend:
17484     p_ws = save_p_ws;
17485 
17486     return retval;
17487 }
17488 
17489 /*
17490  * "searchpair()" function
17491  */
17492     static void
17493 f_searchpair(typval_T *argvars, typval_T *rettv)
17494 {
17495     rettv->vval.v_number = searchpair_cmn(argvars, NULL);
17496 }
17497 
17498 /*
17499  * "searchpairpos()" function
17500  */
17501     static void
17502 f_searchpairpos(typval_T *argvars, typval_T *rettv)
17503 {
17504     pos_T	match_pos;
17505     int		lnum = 0;
17506     int		col = 0;
17507 
17508     if (rettv_list_alloc(rettv) == FAIL)
17509 	return;
17510 
17511     if (searchpair_cmn(argvars, &match_pos) > 0)
17512     {
17513 	lnum = match_pos.lnum;
17514 	col = match_pos.col;
17515     }
17516 
17517     list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
17518     list_append_number(rettv->vval.v_list, (varnumber_T)col);
17519 }
17520 
17521 /*
17522  * Search for a start/middle/end thing.
17523  * Used by searchpair(), see its documentation for the details.
17524  * Returns 0 or -1 for no match,
17525  */
17526     long
17527 do_searchpair(
17528     char_u	*spat,	    /* start pattern */
17529     char_u	*mpat,	    /* middle pattern */
17530     char_u	*epat,	    /* end pattern */
17531     int		dir,	    /* BACKWARD or FORWARD */
17532     char_u	*skip,	    /* skip expression */
17533     int		flags,	    /* SP_SETPCMARK and other SP_ values */
17534     pos_T	*match_pos,
17535     linenr_T	lnum_stop,  /* stop at this line if not zero */
17536     long	time_limit UNUSED) /* stop after this many msec */
17537 {
17538     char_u	*save_cpo;
17539     char_u	*pat, *pat2 = NULL, *pat3 = NULL;
17540     long	retval = 0;
17541     pos_T	pos;
17542     pos_T	firstpos;
17543     pos_T	foundpos;
17544     pos_T	save_cursor;
17545     pos_T	save_pos;
17546     int		n;
17547     int		r;
17548     int		nest = 1;
17549     int		err;
17550     int		options = SEARCH_KEEP;
17551     proftime_T	tm;
17552 
17553     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
17554     save_cpo = p_cpo;
17555     p_cpo = empty_option;
17556 
17557 #ifdef FEAT_RELTIME
17558     /* Set the time limit, if there is one. */
17559     profile_setlimit(time_limit, &tm);
17560 #endif
17561 
17562     /* Make two search patterns: start/end (pat2, for in nested pairs) and
17563      * start/middle/end (pat3, for the top pair). */
17564     pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
17565     pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
17566     if (pat2 == NULL || pat3 == NULL)
17567 	goto theend;
17568     sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
17569     if (*mpat == NUL)
17570 	STRCPY(pat3, pat2);
17571     else
17572 	sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
17573 							    spat, epat, mpat);
17574     if (flags & SP_START)
17575 	options |= SEARCH_START;
17576 
17577     save_cursor = curwin->w_cursor;
17578     pos = curwin->w_cursor;
17579     clearpos(&firstpos);
17580     clearpos(&foundpos);
17581     pat = pat3;
17582     for (;;)
17583     {
17584 	n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
17585 					   options, RE_SEARCH, lnum_stop, &tm);
17586 	if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
17587 	    /* didn't find it or found the first match again: FAIL */
17588 	    break;
17589 
17590 	if (firstpos.lnum == 0)
17591 	    firstpos = pos;
17592 	if (equalpos(pos, foundpos))
17593 	{
17594 	    /* Found the same position again.  Can happen with a pattern that
17595 	     * has "\zs" at the end and searching backwards.  Advance one
17596 	     * character and try again. */
17597 	    if (dir == BACKWARD)
17598 		decl(&pos);
17599 	    else
17600 		incl(&pos);
17601 	}
17602 	foundpos = pos;
17603 
17604 	/* clear the start flag to avoid getting stuck here */
17605 	options &= ~SEARCH_START;
17606 
17607 	/* If the skip pattern matches, ignore this match. */
17608 	if (*skip != NUL)
17609 	{
17610 	    save_pos = curwin->w_cursor;
17611 	    curwin->w_cursor = pos;
17612 	    r = eval_to_bool(skip, &err, NULL, FALSE);
17613 	    curwin->w_cursor = save_pos;
17614 	    if (err)
17615 	    {
17616 		/* Evaluating {skip} caused an error, break here. */
17617 		curwin->w_cursor = save_cursor;
17618 		retval = -1;
17619 		break;
17620 	    }
17621 	    if (r)
17622 		continue;
17623 	}
17624 
17625 	if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2))
17626 	{
17627 	    /* Found end when searching backwards or start when searching
17628 	     * forward: nested pair. */
17629 	    ++nest;
17630 	    pat = pat2;		/* nested, don't search for middle */
17631 	}
17632 	else
17633 	{
17634 	    /* Found end when searching forward or start when searching
17635 	     * backward: end of (nested) pair; or found middle in outer pair. */
17636 	    if (--nest == 1)
17637 		pat = pat3;	/* outer level, search for middle */
17638 	}
17639 
17640 	if (nest == 0)
17641 	{
17642 	    /* Found the match: return matchcount or line number. */
17643 	    if (flags & SP_RETCOUNT)
17644 		++retval;
17645 	    else
17646 		retval = pos.lnum;
17647 	    if (flags & SP_SETPCMARK)
17648 		setpcmark();
17649 	    curwin->w_cursor = pos;
17650 	    if (!(flags & SP_REPEAT))
17651 		break;
17652 	    nest = 1;	    /* search for next unmatched */
17653 	}
17654     }
17655 
17656     if (match_pos != NULL)
17657     {
17658 	/* Store the match cursor position */
17659 	match_pos->lnum = curwin->w_cursor.lnum;
17660 	match_pos->col = curwin->w_cursor.col + 1;
17661     }
17662 
17663     /* If 'n' flag is used or search failed: restore cursor position. */
17664     if ((flags & SP_NOMOVE) || retval == 0)
17665 	curwin->w_cursor = save_cursor;
17666 
17667 theend:
17668     vim_free(pat2);
17669     vim_free(pat3);
17670     if (p_cpo == empty_option)
17671 	p_cpo = save_cpo;
17672     else
17673 	/* Darn, evaluating the {skip} expression changed the value. */
17674 	free_string_option(save_cpo);
17675 
17676     return retval;
17677 }
17678 
17679 /*
17680  * "searchpos()" function
17681  */
17682     static void
17683 f_searchpos(typval_T *argvars, typval_T *rettv)
17684 {
17685     pos_T	match_pos;
17686     int		lnum = 0;
17687     int		col = 0;
17688     int		n;
17689     int		flags = 0;
17690 
17691     if (rettv_list_alloc(rettv) == FAIL)
17692 	return;
17693 
17694     n = search_cmn(argvars, &match_pos, &flags);
17695     if (n > 0)
17696     {
17697 	lnum = match_pos.lnum;
17698 	col = match_pos.col;
17699     }
17700 
17701     list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
17702     list_append_number(rettv->vval.v_list, (varnumber_T)col);
17703     if (flags & SP_SUBPAT)
17704 	list_append_number(rettv->vval.v_list, (varnumber_T)n);
17705 }
17706 
17707     static void
17708 f_server2client(typval_T *argvars UNUSED, typval_T *rettv)
17709 {
17710 #ifdef FEAT_CLIENTSERVER
17711     char_u	buf[NUMBUFLEN];
17712     char_u	*server = get_tv_string_chk(&argvars[0]);
17713     char_u	*reply = get_tv_string_buf_chk(&argvars[1], buf);
17714 
17715     rettv->vval.v_number = -1;
17716     if (server == NULL || reply == NULL)
17717 	return;
17718     if (check_restricted() || check_secure())
17719 	return;
17720 # ifdef FEAT_X11
17721     if (check_connection() == FAIL)
17722 	return;
17723 # endif
17724 
17725     if (serverSendReply(server, reply) < 0)
17726     {
17727 	EMSG(_("E258: Unable to send to client"));
17728 	return;
17729     }
17730     rettv->vval.v_number = 0;
17731 #else
17732     rettv->vval.v_number = -1;
17733 #endif
17734 }
17735 
17736     static void
17737 f_serverlist(typval_T *argvars UNUSED, typval_T *rettv)
17738 {
17739     char_u	*r = NULL;
17740 
17741 #ifdef FEAT_CLIENTSERVER
17742 # ifdef WIN32
17743     r = serverGetVimNames();
17744 # else
17745     make_connection();
17746     if (X_DISPLAY != NULL)
17747 	r = serverGetVimNames(X_DISPLAY);
17748 # endif
17749 #endif
17750     rettv->v_type = VAR_STRING;
17751     rettv->vval.v_string = r;
17752 }
17753 
17754 /*
17755  * "setbufvar()" function
17756  */
17757     static void
17758 f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
17759 {
17760     buf_T	*buf;
17761     aco_save_T	aco;
17762     char_u	*varname, *bufvarname;
17763     typval_T	*varp;
17764     char_u	nbuf[NUMBUFLEN];
17765 
17766     if (check_restricted() || check_secure())
17767 	return;
17768     (void)get_tv_number(&argvars[0]);	    /* issue errmsg if type error */
17769     varname = get_tv_string_chk(&argvars[1]);
17770     buf = get_buf_tv(&argvars[0], FALSE);
17771     varp = &argvars[2];
17772 
17773     if (buf != NULL && varname != NULL && varp != NULL)
17774     {
17775 	/* set curbuf to be our buf, temporarily */
17776 	aucmd_prepbuf(&aco, buf);
17777 
17778 	if (*varname == '&')
17779 	{
17780 	    long	numval;
17781 	    char_u	*strval;
17782 	    int		error = FALSE;
17783 
17784 	    ++varname;
17785 	    numval = get_tv_number_chk(varp, &error);
17786 	    strval = get_tv_string_buf_chk(varp, nbuf);
17787 	    if (!error && strval != NULL)
17788 		set_option_value(varname, numval, strval, OPT_LOCAL);
17789 	}
17790 	else
17791 	{
17792 	    bufvarname = alloc((unsigned)STRLEN(varname) + 3);
17793 	    if (bufvarname != NULL)
17794 	    {
17795 		STRCPY(bufvarname, "b:");
17796 		STRCPY(bufvarname + 2, varname);
17797 		set_var(bufvarname, varp, TRUE);
17798 		vim_free(bufvarname);
17799 	    }
17800 	}
17801 
17802 	/* reset notion of buffer */
17803 	aucmd_restbuf(&aco);
17804     }
17805 }
17806 
17807     static void
17808 f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED)
17809 {
17810     dict_T	*d;
17811     dictitem_T	*di;
17812     char_u	*csearch;
17813 
17814     if (argvars[0].v_type != VAR_DICT)
17815     {
17816 	EMSG(_(e_dictreq));
17817 	return;
17818     }
17819 
17820     if ((d = argvars[0].vval.v_dict) != NULL)
17821     {
17822 	csearch = get_dict_string(d, (char_u *)"char", FALSE);
17823 	if (csearch != NULL)
17824 	{
17825 #ifdef FEAT_MBYTE
17826 	    if (enc_utf8)
17827 	    {
17828 		int pcc[MAX_MCO];
17829 		int c = utfc_ptr2char(csearch, pcc);
17830 
17831 		set_last_csearch(c, csearch, utfc_ptr2len(csearch));
17832 	    }
17833 	    else
17834 #endif
17835 		set_last_csearch(PTR2CHAR(csearch),
17836 						csearch, MB_PTR2LEN(csearch));
17837 	}
17838 
17839 	di = dict_find(d, (char_u *)"forward", -1);
17840 	if (di != NULL)
17841 	    set_csearch_direction(get_tv_number(&di->di_tv)
17842 							? FORWARD : BACKWARD);
17843 
17844 	di = dict_find(d, (char_u *)"until", -1);
17845 	if (di != NULL)
17846 	    set_csearch_until(!!get_tv_number(&di->di_tv));
17847     }
17848 }
17849 
17850 /*
17851  * "setcmdpos()" function
17852  */
17853     static void
17854 f_setcmdpos(typval_T *argvars, typval_T *rettv)
17855 {
17856     int		pos = (int)get_tv_number(&argvars[0]) - 1;
17857 
17858     if (pos >= 0)
17859 	rettv->vval.v_number = set_cmdline_pos(pos);
17860 }
17861 
17862 /*
17863  * "setfperm({fname}, {mode})" function
17864  */
17865     static void
17866 f_setfperm(typval_T *argvars, typval_T *rettv)
17867 {
17868     char_u	*fname;
17869     char_u	modebuf[NUMBUFLEN];
17870     char_u	*mode_str;
17871     int		i;
17872     int		mask;
17873     int		mode = 0;
17874 
17875     rettv->vval.v_number = 0;
17876     fname = get_tv_string_chk(&argvars[0]);
17877     if (fname == NULL)
17878 	return;
17879     mode_str = get_tv_string_buf_chk(&argvars[1], modebuf);
17880     if (mode_str == NULL)
17881 	return;
17882     if (STRLEN(mode_str) != 9)
17883     {
17884 	EMSG2(_(e_invarg2), mode_str);
17885 	return;
17886     }
17887 
17888     mask = 1;
17889     for (i = 8; i >= 0; --i)
17890     {
17891 	if (mode_str[i] != '-')
17892 	    mode |= mask;
17893 	mask = mask << 1;
17894     }
17895     rettv->vval.v_number = mch_setperm(fname, mode) == OK;
17896 }
17897 
17898 /*
17899  * "setline()" function
17900  */
17901     static void
17902 f_setline(typval_T *argvars, typval_T *rettv)
17903 {
17904     linenr_T	lnum;
17905     char_u	*line = NULL;
17906     list_T	*l = NULL;
17907     listitem_T	*li = NULL;
17908     long	added = 0;
17909     linenr_T	lcount = curbuf->b_ml.ml_line_count;
17910 
17911     lnum = get_tv_lnum(&argvars[0]);
17912     if (argvars[1].v_type == VAR_LIST)
17913     {
17914 	l = argvars[1].vval.v_list;
17915 	li = l->lv_first;
17916     }
17917     else
17918 	line = get_tv_string_chk(&argvars[1]);
17919 
17920     /* default result is zero == OK */
17921     for (;;)
17922     {
17923 	if (l != NULL)
17924 	{
17925 	    /* list argument, get next string */
17926 	    if (li == NULL)
17927 		break;
17928 	    line = get_tv_string_chk(&li->li_tv);
17929 	    li = li->li_next;
17930 	}
17931 
17932 	rettv->vval.v_number = 1;	/* FAIL */
17933 	if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
17934 	    break;
17935 
17936 	/* When coming here from Insert mode, sync undo, so that this can be
17937 	 * undone separately from what was previously inserted. */
17938 	if (u_sync_once == 2)
17939 	{
17940 	    u_sync_once = 1; /* notify that u_sync() was called */
17941 	    u_sync(TRUE);
17942 	}
17943 
17944 	if (lnum <= curbuf->b_ml.ml_line_count)
17945 	{
17946 	    /* existing line, replace it */
17947 	    if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK)
17948 	    {
17949 		changed_bytes(lnum, 0);
17950 		if (lnum == curwin->w_cursor.lnum)
17951 		    check_cursor_col();
17952 		rettv->vval.v_number = 0;	/* OK */
17953 	    }
17954 	}
17955 	else if (added > 0 || u_save(lnum - 1, lnum) == OK)
17956 	{
17957 	    /* lnum is one past the last line, append the line */
17958 	    ++added;
17959 	    if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
17960 		rettv->vval.v_number = 0;	/* OK */
17961 	}
17962 
17963 	if (l == NULL)			/* only one string argument */
17964 	    break;
17965 	++lnum;
17966     }
17967 
17968     if (added > 0)
17969 	appended_lines_mark(lcount, added);
17970 }
17971 
17972 static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv);
17973 
17974 /*
17975  * Used by "setqflist()" and "setloclist()" functions
17976  */
17977     static void
17978 set_qf_ll_list(
17979     win_T	*wp UNUSED,
17980     typval_T	*list_arg UNUSED,
17981     typval_T	*action_arg UNUSED,
17982     typval_T	*rettv)
17983 {
17984 #ifdef FEAT_QUICKFIX
17985     char_u	*act;
17986     int		action = ' ';
17987 #endif
17988 
17989     rettv->vval.v_number = -1;
17990 
17991 #ifdef FEAT_QUICKFIX
17992     if (list_arg->v_type != VAR_LIST)
17993 	EMSG(_(e_listreq));
17994     else
17995     {
17996 	list_T  *l = list_arg->vval.v_list;
17997 
17998 	if (action_arg->v_type == VAR_STRING)
17999 	{
18000 	    act = get_tv_string_chk(action_arg);
18001 	    if (act == NULL)
18002 		return;		/* type error; errmsg already given */
18003 	    if (*act == 'a' || *act == 'r')
18004 		action = *act;
18005 	}
18006 
18007 	if (l != NULL && set_errorlist(wp, l, action,
18008 	       (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
18009 	    rettv->vval.v_number = 0;
18010     }
18011 #endif
18012 }
18013 
18014 /*
18015  * "setloclist()" function
18016  */
18017     static void
18018 f_setloclist(typval_T *argvars, typval_T *rettv)
18019 {
18020     win_T	*win;
18021 
18022     rettv->vval.v_number = -1;
18023 
18024     win = find_win_by_nr(&argvars[0], NULL);
18025     if (win != NULL)
18026 	set_qf_ll_list(win, &argvars[1], &argvars[2], rettv);
18027 }
18028 
18029 /*
18030  * "setmatches()" function
18031  */
18032     static void
18033 f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
18034 {
18035 #ifdef FEAT_SEARCH_EXTRA
18036     list_T	*l;
18037     listitem_T	*li;
18038     dict_T	*d;
18039     list_T	*s = NULL;
18040 
18041     rettv->vval.v_number = -1;
18042     if (argvars[0].v_type != VAR_LIST)
18043     {
18044 	EMSG(_(e_listreq));
18045 	return;
18046     }
18047     if ((l = argvars[0].vval.v_list) != NULL)
18048     {
18049 
18050 	/* To some extent make sure that we are dealing with a list from
18051 	 * "getmatches()". */
18052 	li = l->lv_first;
18053 	while (li != NULL)
18054 	{
18055 	    if (li->li_tv.v_type != VAR_DICT
18056 		    || (d = li->li_tv.vval.v_dict) == NULL)
18057 	    {
18058 		EMSG(_(e_invarg));
18059 		return;
18060 	    }
18061 	    if (!(dict_find(d, (char_u *)"group", -1) != NULL
18062 			&& (dict_find(d, (char_u *)"pattern", -1) != NULL
18063 			    || dict_find(d, (char_u *)"pos1", -1) != NULL)
18064 			&& dict_find(d, (char_u *)"priority", -1) != NULL
18065 			&& dict_find(d, (char_u *)"id", -1) != NULL))
18066 	    {
18067 		EMSG(_(e_invarg));
18068 		return;
18069 	    }
18070 	    li = li->li_next;
18071 	}
18072 
18073 	clear_matches(curwin);
18074 	li = l->lv_first;
18075 	while (li != NULL)
18076 	{
18077 	    int		i = 0;
18078 	    char_u	buf[5];
18079 	    dictitem_T  *di;
18080 	    char_u	*group;
18081 	    int		priority;
18082 	    int		id;
18083 	    char_u	*conceal;
18084 
18085 	    d = li->li_tv.vval.v_dict;
18086 	    if (dict_find(d, (char_u *)"pattern", -1) == NULL)
18087 	    {
18088 		if (s == NULL)
18089 		{
18090 		    s = list_alloc();
18091 		    if (s == NULL)
18092 			return;
18093 		}
18094 
18095 		/* match from matchaddpos() */
18096 		for (i = 1; i < 9; i++)
18097 		{
18098 		    sprintf((char *)buf, (char *)"pos%d", i);
18099 		    if ((di = dict_find(d, (char_u *)buf, -1)) != NULL)
18100 		    {
18101 			if (di->di_tv.v_type != VAR_LIST)
18102 			    return;
18103 
18104 			list_append_tv(s, &di->di_tv);
18105 			s->lv_refcount++;
18106 		    }
18107 		    else
18108 			break;
18109 		}
18110 	    }
18111 
18112 	    group = get_dict_string(d, (char_u *)"group", FALSE);
18113 	    priority = (int)get_dict_number(d, (char_u *)"priority");
18114 	    id = (int)get_dict_number(d, (char_u *)"id");
18115 	    conceal = dict_find(d, (char_u *)"conceal", -1) != NULL
18116 			      ? get_dict_string(d, (char_u *)"conceal", FALSE)
18117 			      : NULL;
18118 	    if (i == 0)
18119 	    {
18120 		match_add(curwin, group,
18121 		    get_dict_string(d, (char_u *)"pattern", FALSE),
18122 		    priority, id, NULL, conceal);
18123 	    }
18124 	    else
18125 	    {
18126 		match_add(curwin, group, NULL, priority, id, s, conceal);
18127 		list_unref(s);
18128 		s = NULL;
18129 	    }
18130 
18131 	    li = li->li_next;
18132 	}
18133 	rettv->vval.v_number = 0;
18134     }
18135 #endif
18136 }
18137 
18138 /*
18139  * "setpos()" function
18140  */
18141     static void
18142 f_setpos(typval_T *argvars, typval_T *rettv)
18143 {
18144     pos_T	pos;
18145     int		fnum;
18146     char_u	*name;
18147     colnr_T	curswant = -1;
18148 
18149     rettv->vval.v_number = -1;
18150     name = get_tv_string_chk(argvars);
18151     if (name != NULL)
18152     {
18153 	if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK)
18154 	{
18155 	    if (--pos.col < 0)
18156 		pos.col = 0;
18157 	    if (name[0] == '.' && name[1] == NUL)
18158 	    {
18159 		/* set cursor */
18160 		if (fnum == curbuf->b_fnum)
18161 		{
18162 		    curwin->w_cursor = pos;
18163 		    if (curswant >= 0)
18164 		    {
18165 			curwin->w_curswant = curswant - 1;
18166 			curwin->w_set_curswant = FALSE;
18167 		    }
18168 		    check_cursor();
18169 		    rettv->vval.v_number = 0;
18170 		}
18171 		else
18172 		    EMSG(_(e_invarg));
18173 	    }
18174 	    else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL)
18175 	    {
18176 		/* set mark */
18177 		if (setmark_pos(name[1], &pos, fnum) == OK)
18178 		    rettv->vval.v_number = 0;
18179 	    }
18180 	    else
18181 		EMSG(_(e_invarg));
18182 	}
18183     }
18184 }
18185 
18186 /*
18187  * "setqflist()" function
18188  */
18189     static void
18190 f_setqflist(typval_T *argvars, typval_T *rettv)
18191 {
18192     set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv);
18193 }
18194 
18195 /*
18196  * "setreg()" function
18197  */
18198     static void
18199 f_setreg(typval_T *argvars, typval_T *rettv)
18200 {
18201     int		regname;
18202     char_u	*strregname;
18203     char_u	*stropt;
18204     char_u	*strval;
18205     int		append;
18206     char_u	yank_type;
18207     long	block_len;
18208 
18209     block_len = -1;
18210     yank_type = MAUTO;
18211     append = FALSE;
18212 
18213     strregname = get_tv_string_chk(argvars);
18214     rettv->vval.v_number = 1;		/* FAIL is default */
18215 
18216     if (strregname == NULL)
18217 	return;		/* type error; errmsg already given */
18218     regname = *strregname;
18219     if (regname == 0 || regname == '@')
18220 	regname = '"';
18221 
18222     if (argvars[2].v_type != VAR_UNKNOWN)
18223     {
18224 	stropt = get_tv_string_chk(&argvars[2]);
18225 	if (stropt == NULL)
18226 	    return;		/* type error */
18227 	for (; *stropt != NUL; ++stropt)
18228 	    switch (*stropt)
18229 	    {
18230 		case 'a': case 'A':	/* append */
18231 		    append = TRUE;
18232 		    break;
18233 		case 'v': case 'c':	/* character-wise selection */
18234 		    yank_type = MCHAR;
18235 		    break;
18236 		case 'V': case 'l':	/* line-wise selection */
18237 		    yank_type = MLINE;
18238 		    break;
18239 		case 'b': case Ctrl_V:	/* block-wise selection */
18240 		    yank_type = MBLOCK;
18241 		    if (VIM_ISDIGIT(stropt[1]))
18242 		    {
18243 			++stropt;
18244 			block_len = getdigits(&stropt) - 1;
18245 			--stropt;
18246 		    }
18247 		    break;
18248 	    }
18249     }
18250 
18251     if (argvars[1].v_type == VAR_LIST)
18252     {
18253 	char_u		**lstval;
18254 	char_u		**allocval;
18255 	char_u		buf[NUMBUFLEN];
18256 	char_u		**curval;
18257 	char_u		**curallocval;
18258 	int		len = argvars[1].vval.v_list->lv_len;
18259 	listitem_T	*li;
18260 
18261 	/* First half: use for pointers to result lines; second half: use for
18262 	 * pointers to allocated copies. */
18263 	lstval = (char_u **)alloc(sizeof(char_u *) * ((len + 1) * 2));
18264 	if (lstval == NULL)
18265 	    return;
18266 	curval = lstval;
18267 	allocval = lstval + len + 2;
18268 	curallocval = allocval;
18269 
18270 	for (li = argvars[1].vval.v_list->lv_first; li != NULL;
18271 							     li = li->li_next)
18272 	{
18273 	    strval = get_tv_string_buf_chk(&li->li_tv, buf);
18274 	    if (strval == NULL)
18275 		goto free_lstval;
18276 	    if (strval == buf)
18277 	    {
18278 		/* Need to make a copy, next get_tv_string_buf_chk() will
18279 		 * overwrite the string. */
18280 		strval = vim_strsave(buf);
18281 		if (strval == NULL)
18282 		    goto free_lstval;
18283 		*curallocval++ = strval;
18284 	    }
18285 	    *curval++ = strval;
18286 	}
18287 	*curval++ = NULL;
18288 
18289 	write_reg_contents_lst(regname, lstval, -1,
18290 						append, yank_type, block_len);
18291 free_lstval:
18292 	while (curallocval > allocval)
18293 	    vim_free(*--curallocval);
18294 	vim_free(lstval);
18295     }
18296     else
18297     {
18298 	strval = get_tv_string_chk(&argvars[1]);
18299 	if (strval == NULL)
18300 	    return;
18301 	write_reg_contents_ex(regname, strval, -1,
18302 						append, yank_type, block_len);
18303     }
18304     rettv->vval.v_number = 0;
18305 }
18306 
18307 /*
18308  * "settabvar()" function
18309  */
18310     static void
18311 f_settabvar(typval_T *argvars, typval_T *rettv)
18312 {
18313 #ifdef FEAT_WINDOWS
18314     tabpage_T	*save_curtab;
18315     tabpage_T	*tp;
18316 #endif
18317     char_u	*varname, *tabvarname;
18318     typval_T	*varp;
18319 
18320     rettv->vval.v_number = 0;
18321 
18322     if (check_restricted() || check_secure())
18323 	return;
18324 
18325 #ifdef FEAT_WINDOWS
18326     tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
18327 #endif
18328     varname = get_tv_string_chk(&argvars[1]);
18329     varp = &argvars[2];
18330 
18331     if (varname != NULL && varp != NULL
18332 #ifdef FEAT_WINDOWS
18333 	    && tp != NULL
18334 #endif
18335 	    )
18336     {
18337 #ifdef FEAT_WINDOWS
18338 	save_curtab = curtab;
18339 	goto_tabpage_tp(tp, FALSE, FALSE);
18340 #endif
18341 
18342 	tabvarname = alloc((unsigned)STRLEN(varname) + 3);
18343 	if (tabvarname != NULL)
18344 	{
18345 	    STRCPY(tabvarname, "t:");
18346 	    STRCPY(tabvarname + 2, varname);
18347 	    set_var(tabvarname, varp, TRUE);
18348 	    vim_free(tabvarname);
18349 	}
18350 
18351 #ifdef FEAT_WINDOWS
18352 	/* Restore current tabpage */
18353 	if (valid_tabpage(save_curtab))
18354 	    goto_tabpage_tp(save_curtab, FALSE, FALSE);
18355 #endif
18356     }
18357 }
18358 
18359 /*
18360  * "settabwinvar()" function
18361  */
18362     static void
18363 f_settabwinvar(typval_T *argvars, typval_T *rettv)
18364 {
18365     setwinvar(argvars, rettv, 1);
18366 }
18367 
18368 /*
18369  * "setwinvar()" function
18370  */
18371     static void
18372 f_setwinvar(typval_T *argvars, typval_T *rettv)
18373 {
18374     setwinvar(argvars, rettv, 0);
18375 }
18376 
18377 /*
18378  * "setwinvar()" and "settabwinvar()" functions
18379  */
18380 
18381     static void
18382 setwinvar(typval_T *argvars, typval_T *rettv UNUSED, int off)
18383 {
18384     win_T	*win;
18385 #ifdef FEAT_WINDOWS
18386     win_T	*save_curwin;
18387     tabpage_T	*save_curtab;
18388     int		need_switch_win;
18389 #endif
18390     char_u	*varname, *winvarname;
18391     typval_T	*varp;
18392     char_u	nbuf[NUMBUFLEN];
18393     tabpage_T	*tp = NULL;
18394 
18395     if (check_restricted() || check_secure())
18396 	return;
18397 
18398 #ifdef FEAT_WINDOWS
18399     if (off == 1)
18400 	tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
18401     else
18402 	tp = curtab;
18403 #endif
18404     win = find_win_by_nr(&argvars[off], tp);
18405     varname = get_tv_string_chk(&argvars[off + 1]);
18406     varp = &argvars[off + 2];
18407 
18408     if (win != NULL && varname != NULL && varp != NULL)
18409     {
18410 #ifdef FEAT_WINDOWS
18411 	need_switch_win = !(tp == curtab && win == curwin);
18412 	if (!need_switch_win
18413 	       || switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK)
18414 #endif
18415 	{
18416 	    if (*varname == '&')
18417 	    {
18418 		long	numval;
18419 		char_u	*strval;
18420 		int		error = FALSE;
18421 
18422 		++varname;
18423 		numval = get_tv_number_chk(varp, &error);
18424 		strval = get_tv_string_buf_chk(varp, nbuf);
18425 		if (!error && strval != NULL)
18426 		    set_option_value(varname, numval, strval, OPT_LOCAL);
18427 	    }
18428 	    else
18429 	    {
18430 		winvarname = alloc((unsigned)STRLEN(varname) + 3);
18431 		if (winvarname != NULL)
18432 		{
18433 		    STRCPY(winvarname, "w:");
18434 		    STRCPY(winvarname + 2, varname);
18435 		    set_var(winvarname, varp, TRUE);
18436 		    vim_free(winvarname);
18437 		}
18438 	    }
18439 	}
18440 #ifdef FEAT_WINDOWS
18441 	if (need_switch_win)
18442 	    restore_win(save_curwin, save_curtab, TRUE);
18443 #endif
18444     }
18445 }
18446 
18447 #ifdef FEAT_CRYPT
18448 /*
18449  * "sha256({string})" function
18450  */
18451     static void
18452 f_sha256(typval_T *argvars, typval_T *rettv)
18453 {
18454     char_u	*p;
18455 
18456     p = get_tv_string(&argvars[0]);
18457     rettv->vval.v_string = vim_strsave(
18458 				    sha256_bytes(p, (int)STRLEN(p), NULL, 0));
18459     rettv->v_type = VAR_STRING;
18460 }
18461 #endif /* FEAT_CRYPT */
18462 
18463 /*
18464  * "shellescape({string})" function
18465  */
18466     static void
18467 f_shellescape(typval_T *argvars, typval_T *rettv)
18468 {
18469     rettv->vval.v_string = vim_strsave_shellescape(
18470 		get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]), TRUE);
18471     rettv->v_type = VAR_STRING;
18472 }
18473 
18474 /*
18475  * shiftwidth() function
18476  */
18477     static void
18478 f_shiftwidth(typval_T *argvars UNUSED, typval_T *rettv)
18479 {
18480     rettv->vval.v_number = get_sw_value(curbuf);
18481 }
18482 
18483 /*
18484  * "simplify()" function
18485  */
18486     static void
18487 f_simplify(typval_T *argvars, typval_T *rettv)
18488 {
18489     char_u	*p;
18490 
18491     p = get_tv_string(&argvars[0]);
18492     rettv->vval.v_string = vim_strsave(p);
18493     simplify_filename(rettv->vval.v_string);	/* simplify in place */
18494     rettv->v_type = VAR_STRING;
18495 }
18496 
18497 #ifdef FEAT_FLOAT
18498 /*
18499  * "sin()" function
18500  */
18501     static void
18502 f_sin(typval_T *argvars, typval_T *rettv)
18503 {
18504     float_T	f = 0.0;
18505 
18506     rettv->v_type = VAR_FLOAT;
18507     if (get_float_arg(argvars, &f) == OK)
18508 	rettv->vval.v_float = sin(f);
18509     else
18510 	rettv->vval.v_float = 0.0;
18511 }
18512 
18513 /*
18514  * "sinh()" function
18515  */
18516     static void
18517 f_sinh(typval_T *argvars, typval_T *rettv)
18518 {
18519     float_T	f = 0.0;
18520 
18521     rettv->v_type = VAR_FLOAT;
18522     if (get_float_arg(argvars, &f) == OK)
18523 	rettv->vval.v_float = sinh(f);
18524     else
18525 	rettv->vval.v_float = 0.0;
18526 }
18527 #endif
18528 
18529 static int
18530 #ifdef __BORLANDC__
18531     _RTLENTRYF
18532 #endif
18533 	item_compare(const void *s1, const void *s2);
18534 static int
18535 #ifdef __BORLANDC__
18536     _RTLENTRYF
18537 #endif
18538 	item_compare2(const void *s1, const void *s2);
18539 
18540 /* struct used in the array that's given to qsort() */
18541 typedef struct
18542 {
18543     listitem_T	*item;
18544     int		idx;
18545 } sortItem_T;
18546 
18547 /* struct storing information about current sort */
18548 typedef struct
18549 {
18550     int		item_compare_ic;
18551     int		item_compare_numeric;
18552     int		item_compare_numbers;
18553 #ifdef FEAT_FLOAT
18554     int		item_compare_float;
18555 #endif
18556     char_u	*item_compare_func;
18557     partial_T	*item_compare_partial;
18558     dict_T	*item_compare_selfdict;
18559     int		item_compare_func_err;
18560     int		item_compare_keep_zero;
18561 } sortinfo_T;
18562 static sortinfo_T	*sortinfo = NULL;
18563 static void	do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort);
18564 #define ITEM_COMPARE_FAIL 999
18565 
18566 /*
18567  * Compare functions for f_sort() and f_uniq() below.
18568  */
18569     static int
18570 #ifdef __BORLANDC__
18571 _RTLENTRYF
18572 #endif
18573 item_compare(const void *s1, const void *s2)
18574 {
18575     sortItem_T  *si1, *si2;
18576     typval_T	*tv1, *tv2;
18577     char_u	*p1, *p2;
18578     char_u	*tofree1 = NULL, *tofree2 = NULL;
18579     int		res;
18580     char_u	numbuf1[NUMBUFLEN];
18581     char_u	numbuf2[NUMBUFLEN];
18582 
18583     si1 = (sortItem_T *)s1;
18584     si2 = (sortItem_T *)s2;
18585     tv1 = &si1->item->li_tv;
18586     tv2 = &si2->item->li_tv;
18587 
18588     if (sortinfo->item_compare_numbers)
18589     {
18590 	long	v1 = get_tv_number(tv1);
18591 	long	v2 = get_tv_number(tv2);
18592 
18593 	return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
18594     }
18595 
18596 #ifdef FEAT_FLOAT
18597     if (sortinfo->item_compare_float)
18598     {
18599 	float_T	v1 = get_tv_float(tv1);
18600 	float_T	v2 = get_tv_float(tv2);
18601 
18602 	return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
18603     }
18604 #endif
18605 
18606     /* tv2string() puts quotes around a string and allocates memory.  Don't do
18607      * that for string variables. Use a single quote when comparing with a
18608      * non-string to do what the docs promise. */
18609     if (tv1->v_type == VAR_STRING)
18610     {
18611 	if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric)
18612 	    p1 = (char_u *)"'";
18613 	else
18614 	    p1 = tv1->vval.v_string;
18615     }
18616     else
18617 	p1 = tv2string(tv1, &tofree1, numbuf1, 0);
18618     if (tv2->v_type == VAR_STRING)
18619     {
18620 	if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric)
18621 	    p2 = (char_u *)"'";
18622 	else
18623 	    p2 = tv2->vval.v_string;
18624     }
18625     else
18626 	p2 = tv2string(tv2, &tofree2, numbuf2, 0);
18627     if (p1 == NULL)
18628 	p1 = (char_u *)"";
18629     if (p2 == NULL)
18630 	p2 = (char_u *)"";
18631     if (!sortinfo->item_compare_numeric)
18632     {
18633 	if (sortinfo->item_compare_ic)
18634 	    res = STRICMP(p1, p2);
18635 	else
18636 	    res = STRCMP(p1, p2);
18637     }
18638     else
18639     {
18640 	double n1, n2;
18641 	n1 = strtod((char *)p1, (char **)&p1);
18642 	n2 = strtod((char *)p2, (char **)&p2);
18643 	res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1;
18644     }
18645 
18646     /* When the result would be zero, compare the item indexes.  Makes the
18647      * sort stable. */
18648     if (res == 0 && !sortinfo->item_compare_keep_zero)
18649 	res = si1->idx > si2->idx ? 1 : -1;
18650 
18651     vim_free(tofree1);
18652     vim_free(tofree2);
18653     return res;
18654 }
18655 
18656     static int
18657 #ifdef __BORLANDC__
18658 _RTLENTRYF
18659 #endif
18660 item_compare2(const void *s1, const void *s2)
18661 {
18662     sortItem_T  *si1, *si2;
18663     int		res;
18664     typval_T	rettv;
18665     typval_T	argv[3];
18666     int		dummy;
18667     char_u	*func_name;
18668     partial_T	*partial = sortinfo->item_compare_partial;
18669 
18670     /* shortcut after failure in previous call; compare all items equal */
18671     if (sortinfo->item_compare_func_err)
18672 	return 0;
18673 
18674     si1 = (sortItem_T *)s1;
18675     si2 = (sortItem_T *)s2;
18676 
18677     if (partial == NULL)
18678 	func_name = sortinfo->item_compare_func;
18679     else
18680 	func_name = partial->pt_name;
18681 
18682     /* Copy the values.  This is needed to be able to set v_lock to VAR_FIXED
18683      * in the copy without changing the original list items. */
18684     copy_tv(&si1->item->li_tv, &argv[0]);
18685     copy_tv(&si2->item->li_tv, &argv[1]);
18686 
18687     rettv.v_type = VAR_UNKNOWN;		/* clear_tv() uses this */
18688     res = call_func(func_name, (int)STRLEN(func_name),
18689 				 &rettv, 2, argv, 0L, 0L, &dummy, TRUE,
18690 				 partial, sortinfo->item_compare_selfdict);
18691     clear_tv(&argv[0]);
18692     clear_tv(&argv[1]);
18693 
18694     if (res == FAIL)
18695 	res = ITEM_COMPARE_FAIL;
18696     else
18697 	res = get_tv_number_chk(&rettv, &sortinfo->item_compare_func_err);
18698     if (sortinfo->item_compare_func_err)
18699 	res = ITEM_COMPARE_FAIL;  /* return value has wrong type */
18700     clear_tv(&rettv);
18701 
18702     /* When the result would be zero, compare the pointers themselves.  Makes
18703      * the sort stable. */
18704     if (res == 0 && !sortinfo->item_compare_keep_zero)
18705 	res = si1->idx > si2->idx ? 1 : -1;
18706 
18707     return res;
18708 }
18709 
18710 /*
18711  * "sort({list})" function
18712  */
18713     static void
18714 do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort)
18715 {
18716     list_T	*l;
18717     listitem_T	*li;
18718     sortItem_T	*ptrs;
18719     sortinfo_T	*old_sortinfo;
18720     sortinfo_T	info;
18721     long	len;
18722     long	i;
18723 
18724     /* Pointer to current info struct used in compare function. Save and
18725      * restore the current one for nested calls. */
18726     old_sortinfo = sortinfo;
18727     sortinfo = &info;
18728 
18729     if (argvars[0].v_type != VAR_LIST)
18730 	EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
18731     else
18732     {
18733 	l = argvars[0].vval.v_list;
18734 	if (l == NULL || tv_check_lock(l->lv_lock,
18735 	     (char_u *)(sort ? N_("sort() argument") : N_("uniq() argument")),
18736 									TRUE))
18737 	    goto theend;
18738 	rettv->vval.v_list = l;
18739 	rettv->v_type = VAR_LIST;
18740 	++l->lv_refcount;
18741 
18742 	len = list_len(l);
18743 	if (len <= 1)
18744 	    goto theend;	/* short list sorts pretty quickly */
18745 
18746 	info.item_compare_ic = FALSE;
18747 	info.item_compare_numeric = FALSE;
18748 	info.item_compare_numbers = FALSE;
18749 #ifdef FEAT_FLOAT
18750 	info.item_compare_float = FALSE;
18751 #endif
18752 	info.item_compare_func = NULL;
18753 	info.item_compare_partial = NULL;
18754 	info.item_compare_selfdict = NULL;
18755 	if (argvars[1].v_type != VAR_UNKNOWN)
18756 	{
18757 	    /* optional second argument: {func} */
18758 	    if (argvars[1].v_type == VAR_FUNC)
18759 		info.item_compare_func = argvars[1].vval.v_string;
18760 	    else if (argvars[1].v_type == VAR_PARTIAL)
18761 		info.item_compare_partial = argvars[1].vval.v_partial;
18762 	    else
18763 	    {
18764 		int	    error = FALSE;
18765 
18766 		i = get_tv_number_chk(&argvars[1], &error);
18767 		if (error)
18768 		    goto theend;	/* type error; errmsg already given */
18769 		if (i == 1)
18770 		    info.item_compare_ic = TRUE;
18771 		else if (argvars[1].v_type != VAR_NUMBER)
18772 		    info.item_compare_func = get_tv_string(&argvars[1]);
18773 		else if (i != 0)
18774 		{
18775 		    EMSG(_(e_invarg));
18776 		    goto theend;
18777 		}
18778 		if (info.item_compare_func != NULL)
18779 		{
18780 		    if (*info.item_compare_func == NUL)
18781 		    {
18782 			/* empty string means default sort */
18783 			info.item_compare_func = NULL;
18784 		    }
18785 		    else if (STRCMP(info.item_compare_func, "n") == 0)
18786 		    {
18787 			info.item_compare_func = NULL;
18788 			info.item_compare_numeric = TRUE;
18789 		    }
18790 		    else if (STRCMP(info.item_compare_func, "N") == 0)
18791 		    {
18792 			info.item_compare_func = NULL;
18793 			info.item_compare_numbers = TRUE;
18794 		    }
18795 #ifdef FEAT_FLOAT
18796 		    else if (STRCMP(info.item_compare_func, "f") == 0)
18797 		    {
18798 			info.item_compare_func = NULL;
18799 			info.item_compare_float = TRUE;
18800 		    }
18801 #endif
18802 		    else if (STRCMP(info.item_compare_func, "i") == 0)
18803 		    {
18804 			info.item_compare_func = NULL;
18805 			info.item_compare_ic = TRUE;
18806 		    }
18807 		}
18808 	    }
18809 
18810 	    if (argvars[2].v_type != VAR_UNKNOWN)
18811 	    {
18812 		/* optional third argument: {dict} */
18813 		if (argvars[2].v_type != VAR_DICT)
18814 		{
18815 		    EMSG(_(e_dictreq));
18816 		    goto theend;
18817 		}
18818 		info.item_compare_selfdict = argvars[2].vval.v_dict;
18819 	    }
18820 	}
18821 
18822 	/* Make an array with each entry pointing to an item in the List. */
18823 	ptrs = (sortItem_T *)alloc((int)(len * sizeof(sortItem_T)));
18824 	if (ptrs == NULL)
18825 	    goto theend;
18826 
18827 	i = 0;
18828 	if (sort)
18829 	{
18830 	    /* sort(): ptrs will be the list to sort */
18831 	    for (li = l->lv_first; li != NULL; li = li->li_next)
18832 	    {
18833 		ptrs[i].item = li;
18834 		ptrs[i].idx = i;
18835 		++i;
18836 	    }
18837 
18838 	    info.item_compare_func_err = FALSE;
18839 	    info.item_compare_keep_zero = FALSE;
18840 	    /* test the compare function */
18841 	    if ((info.item_compare_func != NULL
18842 					 || info.item_compare_partial != NULL)
18843 		    && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
18844 							 == ITEM_COMPARE_FAIL)
18845 		EMSG(_("E702: Sort compare function failed"));
18846 	    else
18847 	    {
18848 		/* Sort the array with item pointers. */
18849 		qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T),
18850 		    info.item_compare_func == NULL
18851 					  && info.item_compare_partial == NULL
18852 					       ? item_compare : item_compare2);
18853 
18854 		if (!info.item_compare_func_err)
18855 		{
18856 		    /* Clear the List and append the items in sorted order. */
18857 		    l->lv_first = l->lv_last = l->lv_idx_item = NULL;
18858 		    l->lv_len = 0;
18859 		    for (i = 0; i < len; ++i)
18860 			list_append(l, ptrs[i].item);
18861 		}
18862 	    }
18863 	}
18864 	else
18865 	{
18866 	    int	(*item_compare_func_ptr)(const void *, const void *);
18867 
18868 	    /* f_uniq(): ptrs will be a stack of items to remove */
18869 	    info.item_compare_func_err = FALSE;
18870 	    info.item_compare_keep_zero = TRUE;
18871 	    item_compare_func_ptr = info.item_compare_func != NULL
18872 					  || info.item_compare_partial != NULL
18873 					       ? item_compare2 : item_compare;
18874 
18875 	    for (li = l->lv_first; li != NULL && li->li_next != NULL;
18876 							     li = li->li_next)
18877 	    {
18878 		if (item_compare_func_ptr((void *)&li, (void *)&li->li_next)
18879 									 == 0)
18880 		    ptrs[i++].item = li;
18881 		if (info.item_compare_func_err)
18882 		{
18883 		    EMSG(_("E882: Uniq compare function failed"));
18884 		    break;
18885 		}
18886 	    }
18887 
18888 	    if (!info.item_compare_func_err)
18889 	    {
18890 		while (--i >= 0)
18891 		{
18892 		    li = ptrs[i].item->li_next;
18893 		    ptrs[i].item->li_next = li->li_next;
18894 		    if (li->li_next != NULL)
18895 			li->li_next->li_prev = ptrs[i].item;
18896 		    else
18897 			l->lv_last = ptrs[i].item;
18898 		    list_fix_watch(l, li);
18899 		    listitem_free(li);
18900 		    l->lv_len--;
18901 		}
18902 	    }
18903 	}
18904 
18905 	vim_free(ptrs);
18906     }
18907 theend:
18908     sortinfo = old_sortinfo;
18909 }
18910 
18911 /*
18912  * "sort({list})" function
18913  */
18914     static void
18915 f_sort(typval_T *argvars, typval_T *rettv)
18916 {
18917     do_sort_uniq(argvars, rettv, TRUE);
18918 }
18919 
18920 /*
18921  * "uniq({list})" function
18922  */
18923     static void
18924 f_uniq(typval_T *argvars, typval_T *rettv)
18925 {
18926     do_sort_uniq(argvars, rettv, FALSE);
18927 }
18928 
18929 /*
18930  * "soundfold({word})" function
18931  */
18932     static void
18933 f_soundfold(typval_T *argvars, typval_T *rettv)
18934 {
18935     char_u	*s;
18936 
18937     rettv->v_type = VAR_STRING;
18938     s = get_tv_string(&argvars[0]);
18939 #ifdef FEAT_SPELL
18940     rettv->vval.v_string = eval_soundfold(s);
18941 #else
18942     rettv->vval.v_string = vim_strsave(s);
18943 #endif
18944 }
18945 
18946 /*
18947  * "spellbadword()" function
18948  */
18949     static void
18950 f_spellbadword(typval_T *argvars UNUSED, typval_T *rettv)
18951 {
18952     char_u	*word = (char_u *)"";
18953     hlf_T	attr = HLF_COUNT;
18954     int		len = 0;
18955 
18956     if (rettv_list_alloc(rettv) == FAIL)
18957 	return;
18958 
18959 #ifdef FEAT_SPELL
18960     if (argvars[0].v_type == VAR_UNKNOWN)
18961     {
18962 	/* Find the start and length of the badly spelled word. */
18963 	len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr);
18964 	if (len != 0)
18965 	    word = ml_get_cursor();
18966     }
18967     else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL)
18968     {
18969 	char_u	*str = get_tv_string_chk(&argvars[0]);
18970 	int	capcol = -1;
18971 
18972 	if (str != NULL)
18973 	{
18974 	    /* Check the argument for spelling. */
18975 	    while (*str != NUL)
18976 	    {
18977 		len = spell_check(curwin, str, &attr, &capcol, FALSE);
18978 		if (attr != HLF_COUNT)
18979 		{
18980 		    word = str;
18981 		    break;
18982 		}
18983 		str += len;
18984 	    }
18985 	}
18986     }
18987 #endif
18988 
18989     list_append_string(rettv->vval.v_list, word, len);
18990     list_append_string(rettv->vval.v_list, (char_u *)(
18991 			attr == HLF_SPB ? "bad" :
18992 			attr == HLF_SPR ? "rare" :
18993 			attr == HLF_SPL ? "local" :
18994 			attr == HLF_SPC ? "caps" :
18995 			""), -1);
18996 }
18997 
18998 /*
18999  * "spellsuggest()" function
19000  */
19001     static void
19002 f_spellsuggest(typval_T *argvars UNUSED, typval_T *rettv)
19003 {
19004 #ifdef FEAT_SPELL
19005     char_u	*str;
19006     int		typeerr = FALSE;
19007     int		maxcount;
19008     garray_T	ga;
19009     int		i;
19010     listitem_T	*li;
19011     int		need_capital = FALSE;
19012 #endif
19013 
19014     if (rettv_list_alloc(rettv) == FAIL)
19015 	return;
19016 
19017 #ifdef FEAT_SPELL
19018     if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL)
19019     {
19020 	str = get_tv_string(&argvars[0]);
19021 	if (argvars[1].v_type != VAR_UNKNOWN)
19022 	{
19023 	    maxcount = get_tv_number_chk(&argvars[1], &typeerr);
19024 	    if (maxcount <= 0)
19025 		return;
19026 	    if (argvars[2].v_type != VAR_UNKNOWN)
19027 	    {
19028 		need_capital = get_tv_number_chk(&argvars[2], &typeerr);
19029 		if (typeerr)
19030 		    return;
19031 	    }
19032 	}
19033 	else
19034 	    maxcount = 25;
19035 
19036 	spell_suggest_list(&ga, str, maxcount, need_capital, FALSE);
19037 
19038 	for (i = 0; i < ga.ga_len; ++i)
19039 	{
19040 	    str = ((char_u **)ga.ga_data)[i];
19041 
19042 	    li = listitem_alloc();
19043 	    if (li == NULL)
19044 		vim_free(str);
19045 	    else
19046 	    {
19047 		li->li_tv.v_type = VAR_STRING;
19048 		li->li_tv.v_lock = 0;
19049 		li->li_tv.vval.v_string = str;
19050 		list_append(rettv->vval.v_list, li);
19051 	    }
19052 	}
19053 	ga_clear(&ga);
19054     }
19055 #endif
19056 }
19057 
19058     static void
19059 f_split(typval_T *argvars, typval_T *rettv)
19060 {
19061     char_u	*str;
19062     char_u	*end;
19063     char_u	*pat = NULL;
19064     regmatch_T	regmatch;
19065     char_u	patbuf[NUMBUFLEN];
19066     char_u	*save_cpo;
19067     int		match;
19068     colnr_T	col = 0;
19069     int		keepempty = FALSE;
19070     int		typeerr = FALSE;
19071 
19072     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
19073     save_cpo = p_cpo;
19074     p_cpo = (char_u *)"";
19075 
19076     str = get_tv_string(&argvars[0]);
19077     if (argvars[1].v_type != VAR_UNKNOWN)
19078     {
19079 	pat = get_tv_string_buf_chk(&argvars[1], patbuf);
19080 	if (pat == NULL)
19081 	    typeerr = TRUE;
19082 	if (argvars[2].v_type != VAR_UNKNOWN)
19083 	    keepempty = get_tv_number_chk(&argvars[2], &typeerr);
19084     }
19085     if (pat == NULL || *pat == NUL)
19086 	pat = (char_u *)"[\\x01- ]\\+";
19087 
19088     if (rettv_list_alloc(rettv) == FAIL)
19089 	return;
19090     if (typeerr)
19091 	return;
19092 
19093     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
19094     if (regmatch.regprog != NULL)
19095     {
19096 	regmatch.rm_ic = FALSE;
19097 	while (*str != NUL || keepempty)
19098 	{
19099 	    if (*str == NUL)
19100 		match = FALSE;	/* empty item at the end */
19101 	    else
19102 		match = vim_regexec_nl(&regmatch, str, col);
19103 	    if (match)
19104 		end = regmatch.startp[0];
19105 	    else
19106 		end = str + STRLEN(str);
19107 	    if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0
19108 			   && *str != NUL && match && end < regmatch.endp[0]))
19109 	    {
19110 		if (list_append_string(rettv->vval.v_list, str,
19111 						    (int)(end - str)) == FAIL)
19112 		    break;
19113 	    }
19114 	    if (!match)
19115 		break;
19116 	    /* Advance to just after the match. */
19117 	    if (regmatch.endp[0] > str)
19118 		col = 0;
19119 	    else
19120 	    {
19121 		/* Don't get stuck at the same match. */
19122 #ifdef FEAT_MBYTE
19123 		col = (*mb_ptr2len)(regmatch.endp[0]);
19124 #else
19125 		col = 1;
19126 #endif
19127 	    }
19128 	    str = regmatch.endp[0];
19129 	}
19130 
19131 	vim_regfree(regmatch.regprog);
19132     }
19133 
19134     p_cpo = save_cpo;
19135 }
19136 
19137 #ifdef FEAT_FLOAT
19138 /*
19139  * "sqrt()" function
19140  */
19141     static void
19142 f_sqrt(typval_T *argvars, typval_T *rettv)
19143 {
19144     float_T	f = 0.0;
19145 
19146     rettv->v_type = VAR_FLOAT;
19147     if (get_float_arg(argvars, &f) == OK)
19148 	rettv->vval.v_float = sqrt(f);
19149     else
19150 	rettv->vval.v_float = 0.0;
19151 }
19152 
19153 /*
19154  * "str2float()" function
19155  */
19156     static void
19157 f_str2float(typval_T *argvars, typval_T *rettv)
19158 {
19159     char_u *p = skipwhite(get_tv_string(&argvars[0]));
19160 
19161     if (*p == '+')
19162 	p = skipwhite(p + 1);
19163     (void)string2float(p, &rettv->vval.v_float);
19164     rettv->v_type = VAR_FLOAT;
19165 }
19166 #endif
19167 
19168 /*
19169  * "str2nr()" function
19170  */
19171     static void
19172 f_str2nr(typval_T *argvars, typval_T *rettv)
19173 {
19174     int		base = 10;
19175     char_u	*p;
19176     long	n;
19177     int		what;
19178 
19179     if (argvars[1].v_type != VAR_UNKNOWN)
19180     {
19181 	base = get_tv_number(&argvars[1]);
19182 	if (base != 2 && base != 8 && base != 10 && base != 16)
19183 	{
19184 	    EMSG(_(e_invarg));
19185 	    return;
19186 	}
19187     }
19188 
19189     p = skipwhite(get_tv_string(&argvars[0]));
19190     if (*p == '+')
19191 	p = skipwhite(p + 1);
19192     switch (base)
19193     {
19194 	case 2: what = STR2NR_BIN + STR2NR_FORCE; break;
19195 	case 8: what = STR2NR_OCT + STR2NR_FORCE; break;
19196 	case 16: what = STR2NR_HEX + STR2NR_FORCE; break;
19197 	default: what = 0;
19198     }
19199     vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
19200     rettv->vval.v_number = n;
19201 }
19202 
19203 #ifdef HAVE_STRFTIME
19204 /*
19205  * "strftime({format}[, {time}])" function
19206  */
19207     static void
19208 f_strftime(typval_T *argvars, typval_T *rettv)
19209 {
19210     char_u	result_buf[256];
19211     struct tm	*curtime;
19212     time_t	seconds;
19213     char_u	*p;
19214 
19215     rettv->v_type = VAR_STRING;
19216 
19217     p = get_tv_string(&argvars[0]);
19218     if (argvars[1].v_type == VAR_UNKNOWN)
19219 	seconds = time(NULL);
19220     else
19221 	seconds = (time_t)get_tv_number(&argvars[1]);
19222     curtime = localtime(&seconds);
19223     /* MSVC returns NULL for an invalid value of seconds. */
19224     if (curtime == NULL)
19225 	rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
19226     else
19227     {
19228 # ifdef FEAT_MBYTE
19229 	vimconv_T   conv;
19230 	char_u	    *enc;
19231 
19232 	conv.vc_type = CONV_NONE;
19233 	enc = enc_locale();
19234 	convert_setup(&conv, p_enc, enc);
19235 	if (conv.vc_type != CONV_NONE)
19236 	    p = string_convert(&conv, p, NULL);
19237 # endif
19238 	if (p != NULL)
19239 	    (void)strftime((char *)result_buf, sizeof(result_buf),
19240 							  (char *)p, curtime);
19241 	else
19242 	    result_buf[0] = NUL;
19243 
19244 # ifdef FEAT_MBYTE
19245 	if (conv.vc_type != CONV_NONE)
19246 	    vim_free(p);
19247 	convert_setup(&conv, enc, p_enc);
19248 	if (conv.vc_type != CONV_NONE)
19249 	    rettv->vval.v_string = string_convert(&conv, result_buf, NULL);
19250 	else
19251 # endif
19252 	    rettv->vval.v_string = vim_strsave(result_buf);
19253 
19254 # ifdef FEAT_MBYTE
19255 	/* Release conversion descriptors */
19256 	convert_setup(&conv, NULL, NULL);
19257 	vim_free(enc);
19258 # endif
19259     }
19260 }
19261 #endif
19262 
19263 /*
19264  * "stridx()" function
19265  */
19266     static void
19267 f_stridx(typval_T *argvars, typval_T *rettv)
19268 {
19269     char_u	buf[NUMBUFLEN];
19270     char_u	*needle;
19271     char_u	*haystack;
19272     char_u	*save_haystack;
19273     char_u	*pos;
19274     int		start_idx;
19275 
19276     needle = get_tv_string_chk(&argvars[1]);
19277     save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf);
19278     rettv->vval.v_number = -1;
19279     if (needle == NULL || haystack == NULL)
19280 	return;		/* type error; errmsg already given */
19281 
19282     if (argvars[2].v_type != VAR_UNKNOWN)
19283     {
19284 	int	    error = FALSE;
19285 
19286 	start_idx = get_tv_number_chk(&argvars[2], &error);
19287 	if (error || start_idx >= (int)STRLEN(haystack))
19288 	    return;
19289 	if (start_idx >= 0)
19290 	    haystack += start_idx;
19291     }
19292 
19293     pos	= (char_u *)strstr((char *)haystack, (char *)needle);
19294     if (pos != NULL)
19295 	rettv->vval.v_number = (varnumber_T)(pos - save_haystack);
19296 }
19297 
19298 /*
19299  * "string()" function
19300  */
19301     static void
19302 f_string(typval_T *argvars, typval_T *rettv)
19303 {
19304     char_u	*tofree;
19305     char_u	numbuf[NUMBUFLEN];
19306 
19307     rettv->v_type = VAR_STRING;
19308     rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf,
19309 								get_copyID());
19310     /* Make a copy if we have a value but it's not in allocated memory. */
19311     if (rettv->vval.v_string != NULL && tofree == NULL)
19312 	rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
19313 }
19314 
19315 /*
19316  * "strlen()" function
19317  */
19318     static void
19319 f_strlen(typval_T *argvars, typval_T *rettv)
19320 {
19321     rettv->vval.v_number = (varnumber_T)(STRLEN(
19322 					      get_tv_string(&argvars[0])));
19323 }
19324 
19325 /*
19326  * "strchars()" function
19327  */
19328     static void
19329 f_strchars(typval_T *argvars, typval_T *rettv)
19330 {
19331     char_u		*s = get_tv_string(&argvars[0]);
19332     int			skipcc = 0;
19333 #ifdef FEAT_MBYTE
19334     varnumber_T		len = 0;
19335     int			(*func_mb_ptr2char_adv)(char_u **pp);
19336 #endif
19337 
19338     if (argvars[1].v_type != VAR_UNKNOWN)
19339 	skipcc = get_tv_number_chk(&argvars[1], NULL);
19340     if (skipcc < 0 || skipcc > 1)
19341 	EMSG(_(e_invarg));
19342     else
19343     {
19344 #ifdef FEAT_MBYTE
19345 	func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
19346 	while (*s != NUL)
19347 	{
19348 	    func_mb_ptr2char_adv(&s);
19349 	    ++len;
19350 	}
19351 	rettv->vval.v_number = len;
19352 #else
19353 	rettv->vval.v_number = (varnumber_T)(STRLEN(s));
19354 #endif
19355     }
19356 }
19357 
19358 /*
19359  * "strdisplaywidth()" function
19360  */
19361     static void
19362 f_strdisplaywidth(typval_T *argvars, typval_T *rettv)
19363 {
19364     char_u	*s = get_tv_string(&argvars[0]);
19365     int		col = 0;
19366 
19367     if (argvars[1].v_type != VAR_UNKNOWN)
19368 	col = get_tv_number(&argvars[1]);
19369 
19370     rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col);
19371 }
19372 
19373 /*
19374  * "strwidth()" function
19375  */
19376     static void
19377 f_strwidth(typval_T *argvars, typval_T *rettv)
19378 {
19379     char_u	*s = get_tv_string(&argvars[0]);
19380 
19381     rettv->vval.v_number = (varnumber_T)(
19382 #ifdef FEAT_MBYTE
19383 	    mb_string2cells(s, -1)
19384 #else
19385 	    STRLEN(s)
19386 #endif
19387 	    );
19388 }
19389 
19390 /*
19391  * "strpart()" function
19392  */
19393     static void
19394 f_strpart(typval_T *argvars, typval_T *rettv)
19395 {
19396     char_u	*p;
19397     int		n;
19398     int		len;
19399     int		slen;
19400     int		error = FALSE;
19401 
19402     p = get_tv_string(&argvars[0]);
19403     slen = (int)STRLEN(p);
19404 
19405     n = get_tv_number_chk(&argvars[1], &error);
19406     if (error)
19407 	len = 0;
19408     else if (argvars[2].v_type != VAR_UNKNOWN)
19409 	len = get_tv_number(&argvars[2]);
19410     else
19411 	len = slen - n;	    /* default len: all bytes that are available. */
19412 
19413     /*
19414      * Only return the overlap between the specified part and the actual
19415      * string.
19416      */
19417     if (n < 0)
19418     {
19419 	len += n;
19420 	n = 0;
19421     }
19422     else if (n > slen)
19423 	n = slen;
19424     if (len < 0)
19425 	len = 0;
19426     else if (n + len > slen)
19427 	len = slen - n;
19428 
19429     rettv->v_type = VAR_STRING;
19430     rettv->vval.v_string = vim_strnsave(p + n, len);
19431 }
19432 
19433 /*
19434  * "strridx()" function
19435  */
19436     static void
19437 f_strridx(typval_T *argvars, typval_T *rettv)
19438 {
19439     char_u	buf[NUMBUFLEN];
19440     char_u	*needle;
19441     char_u	*haystack;
19442     char_u	*rest;
19443     char_u	*lastmatch = NULL;
19444     int		haystack_len, end_idx;
19445 
19446     needle = get_tv_string_chk(&argvars[1]);
19447     haystack = get_tv_string_buf_chk(&argvars[0], buf);
19448 
19449     rettv->vval.v_number = -1;
19450     if (needle == NULL || haystack == NULL)
19451 	return;		/* type error; errmsg already given */
19452 
19453     haystack_len = (int)STRLEN(haystack);
19454     if (argvars[2].v_type != VAR_UNKNOWN)
19455     {
19456 	/* Third argument: upper limit for index */
19457 	end_idx = get_tv_number_chk(&argvars[2], NULL);
19458 	if (end_idx < 0)
19459 	    return;	/* can never find a match */
19460     }
19461     else
19462 	end_idx = haystack_len;
19463 
19464     if (*needle == NUL)
19465     {
19466 	/* Empty string matches past the end. */
19467 	lastmatch = haystack + end_idx;
19468     }
19469     else
19470     {
19471 	for (rest = haystack; *rest != '\0'; ++rest)
19472 	{
19473 	    rest = (char_u *)strstr((char *)rest, (char *)needle);
19474 	    if (rest == NULL || rest > haystack + end_idx)
19475 		break;
19476 	    lastmatch = rest;
19477 	}
19478     }
19479 
19480     if (lastmatch == NULL)
19481 	rettv->vval.v_number = -1;
19482     else
19483 	rettv->vval.v_number = (varnumber_T)(lastmatch - haystack);
19484 }
19485 
19486 /*
19487  * "strtrans()" function
19488  */
19489     static void
19490 f_strtrans(typval_T *argvars, typval_T *rettv)
19491 {
19492     rettv->v_type = VAR_STRING;
19493     rettv->vval.v_string = transstr(get_tv_string(&argvars[0]));
19494 }
19495 
19496 /*
19497  * "submatch()" function
19498  */
19499     static void
19500 f_submatch(typval_T *argvars, typval_T *rettv)
19501 {
19502     int		error = FALSE;
19503     int		no;
19504     int		retList = 0;
19505 
19506     no = (int)get_tv_number_chk(&argvars[0], &error);
19507     if (error)
19508 	return;
19509     error = FALSE;
19510     if (argvars[1].v_type != VAR_UNKNOWN)
19511 	retList = get_tv_number_chk(&argvars[1], &error);
19512     if (error)
19513 	return;
19514 
19515     if (retList == 0)
19516     {
19517 	rettv->v_type = VAR_STRING;
19518 	rettv->vval.v_string = reg_submatch(no);
19519     }
19520     else
19521     {
19522 	rettv->v_type = VAR_LIST;
19523 	rettv->vval.v_list = reg_submatch_list(no);
19524     }
19525 }
19526 
19527 /*
19528  * "substitute()" function
19529  */
19530     static void
19531 f_substitute(typval_T *argvars, typval_T *rettv)
19532 {
19533     char_u	patbuf[NUMBUFLEN];
19534     char_u	subbuf[NUMBUFLEN];
19535     char_u	flagsbuf[NUMBUFLEN];
19536 
19537     char_u	*str = get_tv_string_chk(&argvars[0]);
19538     char_u	*pat = get_tv_string_buf_chk(&argvars[1], patbuf);
19539     char_u	*sub = get_tv_string_buf_chk(&argvars[2], subbuf);
19540     char_u	*flg = get_tv_string_buf_chk(&argvars[3], flagsbuf);
19541 
19542     rettv->v_type = VAR_STRING;
19543     if (str == NULL || pat == NULL || sub == NULL || flg == NULL)
19544 	rettv->vval.v_string = NULL;
19545     else
19546 	rettv->vval.v_string = do_string_sub(str, pat, sub, flg);
19547 }
19548 
19549 /*
19550  * "synID(lnum, col, trans)" function
19551  */
19552     static void
19553 f_synID(typval_T *argvars UNUSED, typval_T *rettv)
19554 {
19555     int		id = 0;
19556 #ifdef FEAT_SYN_HL
19557     long	lnum;
19558     long	col;
19559     int		trans;
19560     int		transerr = FALSE;
19561 
19562     lnum = get_tv_lnum(argvars);		/* -1 on type error */
19563     col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
19564     trans = get_tv_number_chk(&argvars[2], &transerr);
19565 
19566     if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
19567 	    && col >= 0 && col < (long)STRLEN(ml_get(lnum)))
19568 	id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE);
19569 #endif
19570 
19571     rettv->vval.v_number = id;
19572 }
19573 
19574 /*
19575  * "synIDattr(id, what [, mode])" function
19576  */
19577     static void
19578 f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv)
19579 {
19580     char_u	*p = NULL;
19581 #ifdef FEAT_SYN_HL
19582     int		id;
19583     char_u	*what;
19584     char_u	*mode;
19585     char_u	modebuf[NUMBUFLEN];
19586     int		modec;
19587 
19588     id = get_tv_number(&argvars[0]);
19589     what = get_tv_string(&argvars[1]);
19590     if (argvars[2].v_type != VAR_UNKNOWN)
19591     {
19592 	mode = get_tv_string_buf(&argvars[2], modebuf);
19593 	modec = TOLOWER_ASC(mode[0]);
19594 	if (modec != 't' && modec != 'c' && modec != 'g')
19595 	    modec = 0;	/* replace invalid with current */
19596     }
19597     else
19598     {
19599 #ifdef FEAT_GUI
19600 	if (gui.in_use)
19601 	    modec = 'g';
19602 	else
19603 #endif
19604 	    if (t_colors > 1)
19605 	    modec = 'c';
19606 	else
19607 	    modec = 't';
19608     }
19609 
19610 
19611     switch (TOLOWER_ASC(what[0]))
19612     {
19613 	case 'b':
19614 		if (TOLOWER_ASC(what[1]) == 'g')	/* bg[#] */
19615 		    p = highlight_color(id, what, modec);
19616 		else					/* bold */
19617 		    p = highlight_has_attr(id, HL_BOLD, modec);
19618 		break;
19619 
19620 	case 'f':					/* fg[#] or font */
19621 		p = highlight_color(id, what, modec);
19622 		break;
19623 
19624 	case 'i':
19625 		if (TOLOWER_ASC(what[1]) == 'n')	/* inverse */
19626 		    p = highlight_has_attr(id, HL_INVERSE, modec);
19627 		else					/* italic */
19628 		    p = highlight_has_attr(id, HL_ITALIC, modec);
19629 		break;
19630 
19631 	case 'n':					/* name */
19632 		p = get_highlight_name(NULL, id - 1);
19633 		break;
19634 
19635 	case 'r':					/* reverse */
19636 		p = highlight_has_attr(id, HL_INVERSE, modec);
19637 		break;
19638 
19639 	case 's':
19640 		if (TOLOWER_ASC(what[1]) == 'p')	/* sp[#] */
19641 		    p = highlight_color(id, what, modec);
19642 		else					/* standout */
19643 		    p = highlight_has_attr(id, HL_STANDOUT, modec);
19644 		break;
19645 
19646 	case 'u':
19647 		if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c')
19648 							/* underline */
19649 		    p = highlight_has_attr(id, HL_UNDERLINE, modec);
19650 		else
19651 							/* undercurl */
19652 		    p = highlight_has_attr(id, HL_UNDERCURL, modec);
19653 		break;
19654     }
19655 
19656     if (p != NULL)
19657 	p = vim_strsave(p);
19658 #endif
19659     rettv->v_type = VAR_STRING;
19660     rettv->vval.v_string = p;
19661 }
19662 
19663 /*
19664  * "synIDtrans(id)" function
19665  */
19666     static void
19667 f_synIDtrans(typval_T *argvars UNUSED, typval_T *rettv)
19668 {
19669     int		id;
19670 
19671 #ifdef FEAT_SYN_HL
19672     id = get_tv_number(&argvars[0]);
19673 
19674     if (id > 0)
19675 	id = syn_get_final_id(id);
19676     else
19677 #endif
19678 	id = 0;
19679 
19680     rettv->vval.v_number = id;
19681 }
19682 
19683 /*
19684  * "synconcealed(lnum, col)" function
19685  */
19686     static void
19687 f_synconcealed(typval_T *argvars UNUSED, typval_T *rettv)
19688 {
19689 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL)
19690     long	lnum;
19691     long	col;
19692     int		syntax_flags = 0;
19693     int		cchar;
19694     int		matchid = 0;
19695     char_u	str[NUMBUFLEN];
19696 #endif
19697 
19698     rettv->v_type = VAR_LIST;
19699     rettv->vval.v_list = NULL;
19700 
19701 #if defined(FEAT_SYN_HL) && defined(FEAT_CONCEAL)
19702     lnum = get_tv_lnum(argvars);		/* -1 on type error */
19703     col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
19704 
19705     vim_memset(str, NUL, sizeof(str));
19706 
19707     if (rettv_list_alloc(rettv) != FAIL)
19708     {
19709 	if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
19710 	    && col >= 0 && col <= (long)STRLEN(ml_get(lnum))
19711 	    && curwin->w_p_cole > 0)
19712 	{
19713 	    (void)syn_get_id(curwin, lnum, col, FALSE, NULL, FALSE);
19714 	    syntax_flags = get_syntax_info(&matchid);
19715 
19716 	    /* get the conceal character */
19717 	    if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3)
19718 	    {
19719 		cchar = syn_get_sub_char();
19720 		if (cchar == NUL && curwin->w_p_cole == 1 && lcs_conceal != NUL)
19721 		    cchar = lcs_conceal;
19722 		if (cchar != NUL)
19723 		{
19724 # ifdef FEAT_MBYTE
19725 		    if (has_mbyte)
19726 			(*mb_char2bytes)(cchar, str);
19727 		    else
19728 # endif
19729 			str[0] = cchar;
19730 		}
19731 	    }
19732 	}
19733 
19734 	list_append_number(rettv->vval.v_list,
19735 					    (syntax_flags & HL_CONCEAL) != 0);
19736 	/* -1 to auto-determine strlen */
19737 	list_append_string(rettv->vval.v_list, str, -1);
19738 	list_append_number(rettv->vval.v_list, matchid);
19739     }
19740 #endif
19741 }
19742 
19743 /*
19744  * "synstack(lnum, col)" function
19745  */
19746     static void
19747 f_synstack(typval_T *argvars UNUSED, typval_T *rettv)
19748 {
19749 #ifdef FEAT_SYN_HL
19750     long	lnum;
19751     long	col;
19752     int		i;
19753     int		id;
19754 #endif
19755 
19756     rettv->v_type = VAR_LIST;
19757     rettv->vval.v_list = NULL;
19758 
19759 #ifdef FEAT_SYN_HL
19760     lnum = get_tv_lnum(argvars);		/* -1 on type error */
19761     col = get_tv_number(&argvars[1]) - 1;	/* -1 on type error */
19762 
19763     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
19764 	    && col >= 0 && col <= (long)STRLEN(ml_get(lnum))
19765 	    && rettv_list_alloc(rettv) != FAIL)
19766     {
19767 	(void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE);
19768 	for (i = 0; ; ++i)
19769 	{
19770 	    id = syn_get_stack_item(i);
19771 	    if (id < 0)
19772 		break;
19773 	    if (list_append_number(rettv->vval.v_list, id) == FAIL)
19774 		break;
19775 	}
19776     }
19777 #endif
19778 }
19779 
19780     static void
19781 get_cmd_output_as_rettv(
19782     typval_T	*argvars,
19783     typval_T	*rettv,
19784     int		retlist)
19785 {
19786     char_u	*res = NULL;
19787     char_u	*p;
19788     char_u	*infile = NULL;
19789     char_u	buf[NUMBUFLEN];
19790     int		err = FALSE;
19791     FILE	*fd;
19792     list_T	*list = NULL;
19793     int		flags = SHELL_SILENT;
19794 
19795     rettv->v_type = VAR_STRING;
19796     rettv->vval.v_string = NULL;
19797     if (check_restricted() || check_secure())
19798 	goto errret;
19799 
19800     if (argvars[1].v_type != VAR_UNKNOWN)
19801     {
19802 	/*
19803 	 * Write the string to a temp file, to be used for input of the shell
19804 	 * command.
19805 	 */
19806 	if ((infile = vim_tempname('i', TRUE)) == NULL)
19807 	{
19808 	    EMSG(_(e_notmp));
19809 	    goto errret;
19810 	}
19811 
19812 	fd = mch_fopen((char *)infile, WRITEBIN);
19813 	if (fd == NULL)
19814 	{
19815 	    EMSG2(_(e_notopen), infile);
19816 	    goto errret;
19817 	}
19818 	if (argvars[1].v_type == VAR_LIST)
19819 	{
19820 	    if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL)
19821 		err = TRUE;
19822 	}
19823 	else
19824 	{
19825 	    size_t len;
19826 
19827 	    p = get_tv_string_buf_chk(&argvars[1], buf);
19828 	    if (p == NULL)
19829 	    {
19830 		fclose(fd);
19831 		goto errret;		/* type error; errmsg already given */
19832 	    }
19833 	    len = STRLEN(p);
19834 	    if (len > 0 && fwrite(p, len, 1, fd) != 1)
19835 		err = TRUE;
19836 	}
19837 	if (fclose(fd) != 0)
19838 	    err = TRUE;
19839 	if (err)
19840 	{
19841 	    EMSG(_("E677: Error writing temp file"));
19842 	    goto errret;
19843 	}
19844     }
19845 
19846     /* Omit SHELL_COOKED when invoked with ":silent".  Avoids that the shell
19847      * echoes typeahead, that messes up the display. */
19848     if (!msg_silent)
19849 	flags += SHELL_COOKED;
19850 
19851     if (retlist)
19852     {
19853 	int		len;
19854 	listitem_T	*li;
19855 	char_u		*s = NULL;
19856 	char_u		*start;
19857 	char_u		*end;
19858 	int		i;
19859 
19860 	res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, &len);
19861 	if (res == NULL)
19862 	    goto errret;
19863 
19864 	list = list_alloc();
19865 	if (list == NULL)
19866 	    goto errret;
19867 
19868 	for (i = 0; i < len; ++i)
19869 	{
19870 	    start = res + i;
19871 	    while (i < len && res[i] != NL)
19872 		++i;
19873 	    end = res + i;
19874 
19875 	    s = alloc((unsigned)(end - start + 1));
19876 	    if (s == NULL)
19877 		goto errret;
19878 
19879 	    for (p = s; start < end; ++p, ++start)
19880 		*p = *start == NUL ? NL : *start;
19881 	    *p = NUL;
19882 
19883 	    li = listitem_alloc();
19884 	    if (li == NULL)
19885 	    {
19886 		vim_free(s);
19887 		goto errret;
19888 	    }
19889 	    li->li_tv.v_type = VAR_STRING;
19890 	    li->li_tv.v_lock = 0;
19891 	    li->li_tv.vval.v_string = s;
19892 	    list_append(list, li);
19893 	}
19894 
19895 	++list->lv_refcount;
19896 	rettv->v_type = VAR_LIST;
19897 	rettv->vval.v_list = list;
19898 	list = NULL;
19899     }
19900     else
19901     {
19902 	res = get_cmd_output(get_tv_string(&argvars[0]), infile, flags, NULL);
19903 #ifdef USE_CR
19904 	/* translate <CR> into <NL> */
19905 	if (res != NULL)
19906 	{
19907 	    char_u	*s;
19908 
19909 	    for (s = res; *s; ++s)
19910 	    {
19911 		if (*s == CAR)
19912 		    *s = NL;
19913 	    }
19914 	}
19915 #else
19916 # ifdef USE_CRNL
19917 	/* translate <CR><NL> into <NL> */
19918 	if (res != NULL)
19919 	{
19920 	    char_u	*s, *d;
19921 
19922 	    d = res;
19923 	    for (s = res; *s; ++s)
19924 	    {
19925 		if (s[0] == CAR && s[1] == NL)
19926 		    ++s;
19927 		*d++ = *s;
19928 	    }
19929 	    *d = NUL;
19930 	}
19931 # endif
19932 #endif
19933 	rettv->vval.v_string = res;
19934 	res = NULL;
19935     }
19936 
19937 errret:
19938     if (infile != NULL)
19939     {
19940 	mch_remove(infile);
19941 	vim_free(infile);
19942     }
19943     if (res != NULL)
19944 	vim_free(res);
19945     if (list != NULL)
19946 	list_free(list, TRUE);
19947 }
19948 
19949 /*
19950  * "system()" function
19951  */
19952     static void
19953 f_system(typval_T *argvars, typval_T *rettv)
19954 {
19955     get_cmd_output_as_rettv(argvars, rettv, FALSE);
19956 }
19957 
19958 /*
19959  * "systemlist()" function
19960  */
19961     static void
19962 f_systemlist(typval_T *argvars, typval_T *rettv)
19963 {
19964     get_cmd_output_as_rettv(argvars, rettv, TRUE);
19965 }
19966 
19967 /*
19968  * "tabpagebuflist()" function
19969  */
19970     static void
19971 f_tabpagebuflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
19972 {
19973 #ifdef FEAT_WINDOWS
19974     tabpage_T	*tp;
19975     win_T	*wp = NULL;
19976 
19977     if (argvars[0].v_type == VAR_UNKNOWN)
19978 	wp = firstwin;
19979     else
19980     {
19981 	tp = find_tabpage((int)get_tv_number(&argvars[0]));
19982 	if (tp != NULL)
19983 	    wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
19984     }
19985     if (wp != NULL && rettv_list_alloc(rettv) != FAIL)
19986     {
19987 	for (; wp != NULL; wp = wp->w_next)
19988 	    if (list_append_number(rettv->vval.v_list,
19989 						wp->w_buffer->b_fnum) == FAIL)
19990 		break;
19991     }
19992 #endif
19993 }
19994 
19995 
19996 /*
19997  * "tabpagenr()" function
19998  */
19999     static void
20000 f_tabpagenr(typval_T *argvars UNUSED, typval_T *rettv)
20001 {
20002     int		nr = 1;
20003 #ifdef FEAT_WINDOWS
20004     char_u	*arg;
20005 
20006     if (argvars[0].v_type != VAR_UNKNOWN)
20007     {
20008 	arg = get_tv_string_chk(&argvars[0]);
20009 	nr = 0;
20010 	if (arg != NULL)
20011 	{
20012 	    if (STRCMP(arg, "$") == 0)
20013 		nr = tabpage_index(NULL) - 1;
20014 	    else
20015 		EMSG2(_(e_invexpr2), arg);
20016 	}
20017     }
20018     else
20019 	nr = tabpage_index(curtab);
20020 #endif
20021     rettv->vval.v_number = nr;
20022 }
20023 
20024 
20025 #ifdef FEAT_WINDOWS
20026 static int get_winnr(tabpage_T *tp, typval_T *argvar);
20027 
20028 /*
20029  * Common code for tabpagewinnr() and winnr().
20030  */
20031     static int
20032 get_winnr(tabpage_T *tp, typval_T *argvar)
20033 {
20034     win_T	*twin;
20035     int		nr = 1;
20036     win_T	*wp;
20037     char_u	*arg;
20038 
20039     twin = (tp == curtab) ? curwin : tp->tp_curwin;
20040     if (argvar->v_type != VAR_UNKNOWN)
20041     {
20042 	arg = get_tv_string_chk(argvar);
20043 	if (arg == NULL)
20044 	    nr = 0;		/* type error; errmsg already given */
20045 	else if (STRCMP(arg, "$") == 0)
20046 	    twin = (tp == curtab) ? lastwin : tp->tp_lastwin;
20047 	else if (STRCMP(arg, "#") == 0)
20048 	{
20049 	    twin = (tp == curtab) ? prevwin : tp->tp_prevwin;
20050 	    if (twin == NULL)
20051 		nr = 0;
20052 	}
20053 	else
20054 	{
20055 	    EMSG2(_(e_invexpr2), arg);
20056 	    nr = 0;
20057 	}
20058     }
20059 
20060     if (nr > 0)
20061 	for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
20062 					      wp != twin; wp = wp->w_next)
20063 	{
20064 	    if (wp == NULL)
20065 	    {
20066 		/* didn't find it in this tabpage */
20067 		nr = 0;
20068 		break;
20069 	    }
20070 	    ++nr;
20071 	}
20072     return nr;
20073 }
20074 #endif
20075 
20076 /*
20077  * "tabpagewinnr()" function
20078  */
20079     static void
20080 f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv)
20081 {
20082     int		nr = 1;
20083 #ifdef FEAT_WINDOWS
20084     tabpage_T	*tp;
20085 
20086     tp = find_tabpage((int)get_tv_number(&argvars[0]));
20087     if (tp == NULL)
20088 	nr = 0;
20089     else
20090 	nr = get_winnr(tp, &argvars[1]);
20091 #endif
20092     rettv->vval.v_number = nr;
20093 }
20094 
20095 
20096 /*
20097  * "tagfiles()" function
20098  */
20099     static void
20100 f_tagfiles(typval_T *argvars UNUSED, typval_T *rettv)
20101 {
20102     char_u	*fname;
20103     tagname_T	tn;
20104     int		first;
20105 
20106     if (rettv_list_alloc(rettv) == FAIL)
20107 	return;
20108     fname = alloc(MAXPATHL);
20109     if (fname == NULL)
20110 	return;
20111 
20112     for (first = TRUE; ; first = FALSE)
20113 	if (get_tagfname(&tn, first, fname) == FAIL
20114 		|| list_append_string(rettv->vval.v_list, fname, -1) == FAIL)
20115 	    break;
20116     tagname_free(&tn);
20117     vim_free(fname);
20118 }
20119 
20120 /*
20121  * "taglist()" function
20122  */
20123     static void
20124 f_taglist(typval_T *argvars, typval_T *rettv)
20125 {
20126     char_u  *tag_pattern;
20127 
20128     tag_pattern = get_tv_string(&argvars[0]);
20129 
20130     rettv->vval.v_number = FALSE;
20131     if (*tag_pattern == NUL)
20132 	return;
20133 
20134     if (rettv_list_alloc(rettv) == OK)
20135 	(void)get_tags(rettv->vval.v_list, tag_pattern);
20136 }
20137 
20138 /*
20139  * "tempname()" function
20140  */
20141     static void
20142 f_tempname(typval_T *argvars UNUSED, typval_T *rettv)
20143 {
20144     static int	x = 'A';
20145 
20146     rettv->v_type = VAR_STRING;
20147     rettv->vval.v_string = vim_tempname(x, FALSE);
20148 
20149     /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different
20150      * names.  Skip 'I' and 'O', they are used for shell redirection. */
20151     do
20152     {
20153 	if (x == 'Z')
20154 	    x = '0';
20155 	else if (x == '9')
20156 	    x = 'A';
20157 	else
20158 	{
20159 #ifdef EBCDIC
20160 	    if (x == 'I')
20161 		x = 'J';
20162 	    else if (x == 'R')
20163 		x = 'S';
20164 	    else
20165 #endif
20166 		++x;
20167 	}
20168     } while (x == 'I' || x == 'O');
20169 }
20170 
20171 /*
20172  * "test(list)" function: Just checking the walls...
20173  */
20174     static void
20175 f_test(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
20176 {
20177     /* Used for unit testing.  Change the code below to your liking. */
20178 #if 0
20179     listitem_T	*li;
20180     list_T	*l;
20181     char_u	*bad, *good;
20182 
20183     if (argvars[0].v_type != VAR_LIST)
20184 	return;
20185     l = argvars[0].vval.v_list;
20186     if (l == NULL)
20187 	return;
20188     li = l->lv_first;
20189     if (li == NULL)
20190 	return;
20191     bad = get_tv_string(&li->li_tv);
20192     li = li->li_next;
20193     if (li == NULL)
20194 	return;
20195     good = get_tv_string(&li->li_tv);
20196     rettv->vval.v_number = test_edit_score(bad, good);
20197 #endif
20198 }
20199 
20200 #ifdef FEAT_FLOAT
20201 /*
20202  * "tan()" function
20203  */
20204     static void
20205 f_tan(typval_T *argvars, typval_T *rettv)
20206 {
20207     float_T	f = 0.0;
20208 
20209     rettv->v_type = VAR_FLOAT;
20210     if (get_float_arg(argvars, &f) == OK)
20211 	rettv->vval.v_float = tan(f);
20212     else
20213 	rettv->vval.v_float = 0.0;
20214 }
20215 
20216 /*
20217  * "tanh()" function
20218  */
20219     static void
20220 f_tanh(typval_T *argvars, typval_T *rettv)
20221 {
20222     float_T	f = 0.0;
20223 
20224     rettv->v_type = VAR_FLOAT;
20225     if (get_float_arg(argvars, &f) == OK)
20226 	rettv->vval.v_float = tanh(f);
20227     else
20228 	rettv->vval.v_float = 0.0;
20229 }
20230 #endif
20231 
20232 #if defined(FEAT_JOB_CHANNEL) || defined(FEAT_TIMERS) || defined(PROTO)
20233 /*
20234  * Get a callback from "arg".  It can be a Funcref or a function name.
20235  * When "arg" is zero return an empty string.
20236  * Return NULL for an invalid argument.
20237  */
20238     char_u *
20239 get_callback(typval_T *arg, partial_T **pp)
20240 {
20241     if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL)
20242     {
20243 	*pp = arg->vval.v_partial;
20244 	++(*pp)->pt_refcount;
20245 	return (*pp)->pt_name;
20246     }
20247     *pp = NULL;
20248     if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING)
20249 	return arg->vval.v_string;
20250     if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0)
20251 	return (char_u *)"";
20252     EMSG(_("E921: Invalid callback argument"));
20253     return NULL;
20254 }
20255 #endif
20256 
20257 #ifdef FEAT_TIMERS
20258 /*
20259  * "timer_start(time, callback [, options])" function
20260  */
20261     static void
20262 f_timer_start(typval_T *argvars, typval_T *rettv)
20263 {
20264     long    msec = get_tv_number(&argvars[0]);
20265     timer_T *timer;
20266     int	    repeat = 0;
20267     char_u  *callback;
20268     dict_T  *dict;
20269 
20270     if (argvars[2].v_type != VAR_UNKNOWN)
20271     {
20272 	if (argvars[2].v_type != VAR_DICT
20273 				   || (dict = argvars[2].vval.v_dict) == NULL)
20274 	{
20275 	    EMSG2(_(e_invarg2), get_tv_string(&argvars[2]));
20276 	    return;
20277 	}
20278 	if (dict_find(dict, (char_u *)"repeat", -1) != NULL)
20279 	    repeat = get_dict_number(dict, (char_u *)"repeat");
20280     }
20281 
20282     timer = create_timer(msec, repeat);
20283     callback = get_callback(&argvars[1], &timer->tr_partial);
20284     if (callback == NULL)
20285     {
20286 	stop_timer(timer);
20287 	rettv->vval.v_number = -1;
20288     }
20289     else
20290     {
20291 	timer->tr_callback = vim_strsave(callback);
20292 	rettv->vval.v_number = timer->tr_id;
20293     }
20294 }
20295 
20296 /*
20297  * "timer_stop(timer)" function
20298  */
20299     static void
20300 f_timer_stop(typval_T *argvars, typval_T *rettv UNUSED)
20301 {
20302     timer_T *timer = find_timer(get_tv_number(&argvars[0]));
20303 
20304     if (timer != NULL)
20305 	stop_timer(timer);
20306 }
20307 #endif
20308 
20309 /*
20310  * "tolower(string)" function
20311  */
20312     static void
20313 f_tolower(typval_T *argvars, typval_T *rettv)
20314 {
20315     char_u	*p;
20316 
20317     p = vim_strsave(get_tv_string(&argvars[0]));
20318     rettv->v_type = VAR_STRING;
20319     rettv->vval.v_string = p;
20320 
20321     if (p != NULL)
20322 	while (*p != NUL)
20323 	{
20324 #ifdef FEAT_MBYTE
20325 	    int		l;
20326 
20327 	    if (enc_utf8)
20328 	    {
20329 		int c, lc;
20330 
20331 		c = utf_ptr2char(p);
20332 		lc = utf_tolower(c);
20333 		l = utf_ptr2len(p);
20334 		/* TODO: reallocate string when byte count changes. */
20335 		if (utf_char2len(lc) == l)
20336 		    utf_char2bytes(lc, p);
20337 		p += l;
20338 	    }
20339 	    else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
20340 		p += l;		/* skip multi-byte character */
20341 	    else
20342 #endif
20343 	    {
20344 		*p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
20345 		++p;
20346 	    }
20347 	}
20348 }
20349 
20350 /*
20351  * "toupper(string)" function
20352  */
20353     static void
20354 f_toupper(typval_T *argvars, typval_T *rettv)
20355 {
20356     rettv->v_type = VAR_STRING;
20357     rettv->vval.v_string = strup_save(get_tv_string(&argvars[0]));
20358 }
20359 
20360 /*
20361  * "tr(string, fromstr, tostr)" function
20362  */
20363     static void
20364 f_tr(typval_T *argvars, typval_T *rettv)
20365 {
20366     char_u	*in_str;
20367     char_u	*fromstr;
20368     char_u	*tostr;
20369     char_u	*p;
20370 #ifdef FEAT_MBYTE
20371     int		inlen;
20372     int		fromlen;
20373     int		tolen;
20374     int		idx;
20375     char_u	*cpstr;
20376     int		cplen;
20377     int		first = TRUE;
20378 #endif
20379     char_u	buf[NUMBUFLEN];
20380     char_u	buf2[NUMBUFLEN];
20381     garray_T	ga;
20382 
20383     in_str = get_tv_string(&argvars[0]);
20384     fromstr = get_tv_string_buf_chk(&argvars[1], buf);
20385     tostr = get_tv_string_buf_chk(&argvars[2], buf2);
20386 
20387     /* Default return value: empty string. */
20388     rettv->v_type = VAR_STRING;
20389     rettv->vval.v_string = NULL;
20390     if (fromstr == NULL || tostr == NULL)
20391 	    return;		/* type error; errmsg already given */
20392     ga_init2(&ga, (int)sizeof(char), 80);
20393 
20394 #ifdef FEAT_MBYTE
20395     if (!has_mbyte)
20396 #endif
20397 	/* not multi-byte: fromstr and tostr must be the same length */
20398 	if (STRLEN(fromstr) != STRLEN(tostr))
20399 	{
20400 #ifdef FEAT_MBYTE
20401 error:
20402 #endif
20403 	    EMSG2(_(e_invarg2), fromstr);
20404 	    ga_clear(&ga);
20405 	    return;
20406 	}
20407 
20408     /* fromstr and tostr have to contain the same number of chars */
20409     while (*in_str != NUL)
20410     {
20411 #ifdef FEAT_MBYTE
20412 	if (has_mbyte)
20413 	{
20414 	    inlen = (*mb_ptr2len)(in_str);
20415 	    cpstr = in_str;
20416 	    cplen = inlen;
20417 	    idx = 0;
20418 	    for (p = fromstr; *p != NUL; p += fromlen)
20419 	    {
20420 		fromlen = (*mb_ptr2len)(p);
20421 		if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0)
20422 		{
20423 		    for (p = tostr; *p != NUL; p += tolen)
20424 		    {
20425 			tolen = (*mb_ptr2len)(p);
20426 			if (idx-- == 0)
20427 			{
20428 			    cplen = tolen;
20429 			    cpstr = p;
20430 			    break;
20431 			}
20432 		    }
20433 		    if (*p == NUL)	/* tostr is shorter than fromstr */
20434 			goto error;
20435 		    break;
20436 		}
20437 		++idx;
20438 	    }
20439 
20440 	    if (first && cpstr == in_str)
20441 	    {
20442 		/* Check that fromstr and tostr have the same number of
20443 		 * (multi-byte) characters.  Done only once when a character
20444 		 * of in_str doesn't appear in fromstr. */
20445 		first = FALSE;
20446 		for (p = tostr; *p != NUL; p += tolen)
20447 		{
20448 		    tolen = (*mb_ptr2len)(p);
20449 		    --idx;
20450 		}
20451 		if (idx != 0)
20452 		    goto error;
20453 	    }
20454 
20455 	    (void)ga_grow(&ga, cplen);
20456 	    mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen);
20457 	    ga.ga_len += cplen;
20458 
20459 	    in_str += inlen;
20460 	}
20461 	else
20462 #endif
20463 	{
20464 	    /* When not using multi-byte chars we can do it faster. */
20465 	    p = vim_strchr(fromstr, *in_str);
20466 	    if (p != NULL)
20467 		ga_append(&ga, tostr[p - fromstr]);
20468 	    else
20469 		ga_append(&ga, *in_str);
20470 	    ++in_str;
20471 	}
20472     }
20473 
20474     /* add a terminating NUL */
20475     (void)ga_grow(&ga, 1);
20476     ga_append(&ga, NUL);
20477 
20478     rettv->vval.v_string = ga.ga_data;
20479 }
20480 
20481 #ifdef FEAT_FLOAT
20482 /*
20483  * "trunc({float})" function
20484  */
20485     static void
20486 f_trunc(typval_T *argvars, typval_T *rettv)
20487 {
20488     float_T	f = 0.0;
20489 
20490     rettv->v_type = VAR_FLOAT;
20491     if (get_float_arg(argvars, &f) == OK)
20492 	/* trunc() is not in C90, use floor() or ceil() instead. */
20493 	rettv->vval.v_float = f > 0 ? floor(f) : ceil(f);
20494     else
20495 	rettv->vval.v_float = 0.0;
20496 }
20497 #endif
20498 
20499 /*
20500  * "type(expr)" function
20501  */
20502     static void
20503 f_type(typval_T *argvars, typval_T *rettv)
20504 {
20505     int n = -1;
20506 
20507     switch (argvars[0].v_type)
20508     {
20509 	case VAR_NUMBER: n = 0; break;
20510 	case VAR_STRING: n = 1; break;
20511 	case VAR_PARTIAL:
20512 	case VAR_FUNC:   n = 2; break;
20513 	case VAR_LIST:   n = 3; break;
20514 	case VAR_DICT:   n = 4; break;
20515 	case VAR_FLOAT:  n = 5; break;
20516 	case VAR_SPECIAL:
20517 	     if (argvars[0].vval.v_number == VVAL_FALSE
20518 		     || argvars[0].vval.v_number == VVAL_TRUE)
20519 		 n = 6;
20520 	     else
20521 		 n = 7;
20522 	     break;
20523 	case VAR_JOB:     n = 8; break;
20524 	case VAR_CHANNEL: n = 9; break;
20525 	case VAR_UNKNOWN:
20526 	     EMSG2(_(e_intern2), "f_type(UNKNOWN)");
20527 	     n = -1;
20528 	     break;
20529     }
20530     rettv->vval.v_number = n;
20531 }
20532 
20533 /*
20534  * "undofile(name)" function
20535  */
20536     static void
20537 f_undofile(typval_T *argvars UNUSED, typval_T *rettv)
20538 {
20539     rettv->v_type = VAR_STRING;
20540 #ifdef FEAT_PERSISTENT_UNDO
20541     {
20542 	char_u *fname = get_tv_string(&argvars[0]);
20543 
20544 	if (*fname == NUL)
20545 	{
20546 	    /* If there is no file name there will be no undo file. */
20547 	    rettv->vval.v_string = NULL;
20548 	}
20549 	else
20550 	{
20551 	    char_u *ffname = FullName_save(fname, FALSE);
20552 
20553 	    if (ffname != NULL)
20554 		rettv->vval.v_string = u_get_undo_file_name(ffname, FALSE);
20555 	    vim_free(ffname);
20556 	}
20557     }
20558 #else
20559     rettv->vval.v_string = NULL;
20560 #endif
20561 }
20562 
20563 /*
20564  * "undotree()" function
20565  */
20566     static void
20567 f_undotree(typval_T *argvars UNUSED, typval_T *rettv)
20568 {
20569     if (rettv_dict_alloc(rettv) == OK)
20570     {
20571 	dict_T *dict = rettv->vval.v_dict;
20572 	list_T *list;
20573 
20574 	dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL);
20575 	dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL);
20576 	dict_add_nr_str(dict, "save_last",
20577 					(long)curbuf->b_u_save_nr_last, NULL);
20578 	dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL);
20579 	dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL);
20580 	dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL);
20581 
20582 	list = list_alloc();
20583 	if (list != NULL)
20584 	{
20585 	    u_eval_tree(curbuf->b_u_oldhead, list);
20586 	    dict_add_list(dict, "entries", list);
20587 	}
20588     }
20589 }
20590 
20591 /*
20592  * "values(dict)" function
20593  */
20594     static void
20595 f_values(typval_T *argvars, typval_T *rettv)
20596 {
20597     dict_list(argvars, rettv, 1);
20598 }
20599 
20600 /*
20601  * "virtcol(string)" function
20602  */
20603     static void
20604 f_virtcol(typval_T *argvars, typval_T *rettv)
20605 {
20606     colnr_T	vcol = 0;
20607     pos_T	*fp;
20608     int		fnum = curbuf->b_fnum;
20609 
20610     fp = var2fpos(&argvars[0], FALSE, &fnum);
20611     if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
20612 						    && fnum == curbuf->b_fnum)
20613     {
20614 	getvvcol(curwin, fp, NULL, NULL, &vcol);
20615 	++vcol;
20616     }
20617 
20618     rettv->vval.v_number = vcol;
20619 }
20620 
20621 /*
20622  * "visualmode()" function
20623  */
20624     static void
20625 f_visualmode(typval_T *argvars, typval_T *rettv)
20626 {
20627     char_u	str[2];
20628 
20629     rettv->v_type = VAR_STRING;
20630     str[0] = curbuf->b_visual_mode_eval;
20631     str[1] = NUL;
20632     rettv->vval.v_string = vim_strsave(str);
20633 
20634     /* A non-zero number or non-empty string argument: reset mode. */
20635     if (non_zero_arg(&argvars[0]))
20636 	curbuf->b_visual_mode_eval = NUL;
20637 }
20638 
20639 /*
20640  * "wildmenumode()" function
20641  */
20642     static void
20643 f_wildmenumode(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
20644 {
20645 #ifdef FEAT_WILDMENU
20646     if (wild_menu_showing)
20647 	rettv->vval.v_number = 1;
20648 #endif
20649 }
20650 
20651 /*
20652  * "winbufnr(nr)" function
20653  */
20654     static void
20655 f_winbufnr(typval_T *argvars, typval_T *rettv)
20656 {
20657     win_T	*wp;
20658 
20659     wp = find_win_by_nr(&argvars[0], NULL);
20660     if (wp == NULL)
20661 	rettv->vval.v_number = -1;
20662     else
20663 	rettv->vval.v_number = wp->w_buffer->b_fnum;
20664 }
20665 
20666 /*
20667  * "wincol()" function
20668  */
20669     static void
20670 f_wincol(typval_T *argvars UNUSED, typval_T *rettv)
20671 {
20672     validate_cursor();
20673     rettv->vval.v_number = curwin->w_wcol + 1;
20674 }
20675 
20676 /*
20677  * "winheight(nr)" function
20678  */
20679     static void
20680 f_winheight(typval_T *argvars, typval_T *rettv)
20681 {
20682     win_T	*wp;
20683 
20684     wp = find_win_by_nr(&argvars[0], NULL);
20685     if (wp == NULL)
20686 	rettv->vval.v_number = -1;
20687     else
20688 	rettv->vval.v_number = wp->w_height;
20689 }
20690 
20691 /*
20692  * "winline()" function
20693  */
20694     static void
20695 f_winline(typval_T *argvars UNUSED, typval_T *rettv)
20696 {
20697     validate_cursor();
20698     rettv->vval.v_number = curwin->w_wrow + 1;
20699 }
20700 
20701 /*
20702  * "winnr()" function
20703  */
20704     static void
20705 f_winnr(typval_T *argvars UNUSED, typval_T *rettv)
20706 {
20707     int		nr = 1;
20708 
20709 #ifdef FEAT_WINDOWS
20710     nr = get_winnr(curtab, &argvars[0]);
20711 #endif
20712     rettv->vval.v_number = nr;
20713 }
20714 
20715 /*
20716  * "winrestcmd()" function
20717  */
20718     static void
20719 f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv)
20720 {
20721 #ifdef FEAT_WINDOWS
20722     win_T	*wp;
20723     int		winnr = 1;
20724     garray_T	ga;
20725     char_u	buf[50];
20726 
20727     ga_init2(&ga, (int)sizeof(char), 70);
20728     for (wp = firstwin; wp != NULL; wp = wp->w_next)
20729     {
20730 	sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height);
20731 	ga_concat(&ga, buf);
20732 	sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width);
20733 	ga_concat(&ga, buf);
20734 	++winnr;
20735     }
20736     ga_append(&ga, NUL);
20737 
20738     rettv->vval.v_string = ga.ga_data;
20739 #else
20740     rettv->vval.v_string = NULL;
20741 #endif
20742     rettv->v_type = VAR_STRING;
20743 }
20744 
20745 /*
20746  * "winrestview()" function
20747  */
20748     static void
20749 f_winrestview(typval_T *argvars, typval_T *rettv UNUSED)
20750 {
20751     dict_T	*dict;
20752 
20753     if (argvars[0].v_type != VAR_DICT
20754 	    || (dict = argvars[0].vval.v_dict) == NULL)
20755 	EMSG(_(e_invarg));
20756     else
20757     {
20758 	if (dict_find(dict, (char_u *)"lnum", -1) != NULL)
20759 	    curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum");
20760 	if (dict_find(dict, (char_u *)"col", -1) != NULL)
20761 	    curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col");
20762 #ifdef FEAT_VIRTUALEDIT
20763 	if (dict_find(dict, (char_u *)"coladd", -1) != NULL)
20764 	    curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd");
20765 #endif
20766 	if (dict_find(dict, (char_u *)"curswant", -1) != NULL)
20767 	{
20768 	    curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant");
20769 	    curwin->w_set_curswant = FALSE;
20770 	}
20771 
20772 	if (dict_find(dict, (char_u *)"topline", -1) != NULL)
20773 	    set_topline(curwin, get_dict_number(dict, (char_u *)"topline"));
20774 #ifdef FEAT_DIFF
20775 	if (dict_find(dict, (char_u *)"topfill", -1) != NULL)
20776 	    curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill");
20777 #endif
20778 	if (dict_find(dict, (char_u *)"leftcol", -1) != NULL)
20779 	    curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol");
20780 	if (dict_find(dict, (char_u *)"skipcol", -1) != NULL)
20781 	    curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol");
20782 
20783 	check_cursor();
20784 	win_new_height(curwin, curwin->w_height);
20785 # ifdef FEAT_WINDOWS
20786 	win_new_width(curwin, W_WIDTH(curwin));
20787 # endif
20788 	changed_window_setting();
20789 
20790 	if (curwin->w_topline <= 0)
20791 	    curwin->w_topline = 1;
20792 	if (curwin->w_topline > curbuf->b_ml.ml_line_count)
20793 	    curwin->w_topline = curbuf->b_ml.ml_line_count;
20794 #ifdef FEAT_DIFF
20795 	check_topfill(curwin, TRUE);
20796 #endif
20797     }
20798 }
20799 
20800 /*
20801  * "winsaveview()" function
20802  */
20803     static void
20804 f_winsaveview(typval_T *argvars UNUSED, typval_T *rettv)
20805 {
20806     dict_T	*dict;
20807 
20808     if (rettv_dict_alloc(rettv) == FAIL)
20809 	return;
20810     dict = rettv->vval.v_dict;
20811 
20812     dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL);
20813     dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL);
20814 #ifdef FEAT_VIRTUALEDIT
20815     dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL);
20816 #endif
20817     update_curswant();
20818     dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL);
20819 
20820     dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL);
20821 #ifdef FEAT_DIFF
20822     dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL);
20823 #endif
20824     dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL);
20825     dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL);
20826 }
20827 
20828 /*
20829  * "winwidth(nr)" function
20830  */
20831     static void
20832 f_winwidth(typval_T *argvars, typval_T *rettv)
20833 {
20834     win_T	*wp;
20835 
20836     wp = find_win_by_nr(&argvars[0], NULL);
20837     if (wp == NULL)
20838 	rettv->vval.v_number = -1;
20839     else
20840 #ifdef FEAT_WINDOWS
20841 	rettv->vval.v_number = wp->w_width;
20842 #else
20843 	rettv->vval.v_number = Columns;
20844 #endif
20845 }
20846 
20847 /*
20848  * "wordcount()" function
20849  */
20850     static void
20851 f_wordcount(typval_T *argvars UNUSED, typval_T *rettv)
20852 {
20853     if (rettv_dict_alloc(rettv) == FAIL)
20854 	return;
20855     cursor_pos_info(rettv->vval.v_dict);
20856 }
20857 
20858 /*
20859  * Write list of strings to file
20860  */
20861     static int
20862 write_list(FILE *fd, list_T *list, int binary)
20863 {
20864     listitem_T	*li;
20865     int		c;
20866     int		ret = OK;
20867     char_u	*s;
20868 
20869     for (li = list->lv_first; li != NULL; li = li->li_next)
20870     {
20871 	for (s = get_tv_string(&li->li_tv); *s != NUL; ++s)
20872 	{
20873 	    if (*s == '\n')
20874 		c = putc(NUL, fd);
20875 	    else
20876 		c = putc(*s, fd);
20877 	    if (c == EOF)
20878 	    {
20879 		ret = FAIL;
20880 		break;
20881 	    }
20882 	}
20883 	if (!binary || li->li_next != NULL)
20884 	    if (putc('\n', fd) == EOF)
20885 	    {
20886 		ret = FAIL;
20887 		break;
20888 	    }
20889 	if (ret == FAIL)
20890 	{
20891 	    EMSG(_(e_write));
20892 	    break;
20893 	}
20894     }
20895     return ret;
20896 }
20897 
20898 /*
20899  * "writefile()" function
20900  */
20901     static void
20902 f_writefile(typval_T *argvars, typval_T *rettv)
20903 {
20904     int		binary = FALSE;
20905     int		append = FALSE;
20906     char_u	*fname;
20907     FILE	*fd;
20908     int		ret = 0;
20909 
20910     if (check_restricted() || check_secure())
20911 	return;
20912 
20913     if (argvars[0].v_type != VAR_LIST)
20914     {
20915 	EMSG2(_(e_listarg), "writefile()");
20916 	return;
20917     }
20918     if (argvars[0].vval.v_list == NULL)
20919 	return;
20920 
20921     if (argvars[2].v_type != VAR_UNKNOWN)
20922     {
20923 	if (vim_strchr(get_tv_string(&argvars[2]), 'b') != NULL)
20924 	    binary = TRUE;
20925 	if (vim_strchr(get_tv_string(&argvars[2]), 'a') != NULL)
20926 	    append = TRUE;
20927     }
20928 
20929     /* Always open the file in binary mode, library functions have a mind of
20930      * their own about CR-LF conversion. */
20931     fname = get_tv_string(&argvars[1]);
20932     if (*fname == NUL || (fd = mch_fopen((char *)fname,
20933 				      append ? APPENDBIN : WRITEBIN)) == NULL)
20934     {
20935 	EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname);
20936 	ret = -1;
20937     }
20938     else
20939     {
20940 	if (write_list(fd, argvars[0].vval.v_list, binary) == FAIL)
20941 	    ret = -1;
20942 	fclose(fd);
20943     }
20944 
20945     rettv->vval.v_number = ret;
20946 }
20947 
20948 /*
20949  * "xor(expr, expr)" function
20950  */
20951     static void
20952 f_xor(typval_T *argvars, typval_T *rettv)
20953 {
20954     rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
20955 					^ get_tv_number_chk(&argvars[1], NULL);
20956 }
20957 
20958 
20959 /*
20960  * Translate a String variable into a position.
20961  * Returns NULL when there is an error.
20962  */
20963     static pos_T *
20964 var2fpos(
20965     typval_T	*varp,
20966     int		dollar_lnum,	/* TRUE when $ is last line */
20967     int		*fnum)		/* set to fnum for '0, 'A, etc. */
20968 {
20969     char_u		*name;
20970     static pos_T	pos;
20971     pos_T		*pp;
20972 
20973     /* Argument can be [lnum, col, coladd]. */
20974     if (varp->v_type == VAR_LIST)
20975     {
20976 	list_T		*l;
20977 	int		len;
20978 	int		error = FALSE;
20979 	listitem_T	*li;
20980 
20981 	l = varp->vval.v_list;
20982 	if (l == NULL)
20983 	    return NULL;
20984 
20985 	/* Get the line number */
20986 	pos.lnum = list_find_nr(l, 0L, &error);
20987 	if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
20988 	    return NULL;	/* invalid line number */
20989 
20990 	/* Get the column number */
20991 	pos.col = list_find_nr(l, 1L, &error);
20992 	if (error)
20993 	    return NULL;
20994 	len = (long)STRLEN(ml_get(pos.lnum));
20995 
20996 	/* We accept "$" for the column number: last column. */
20997 	li = list_find(l, 1L);
20998 	if (li != NULL && li->li_tv.v_type == VAR_STRING
20999 		&& li->li_tv.vval.v_string != NULL
21000 		&& STRCMP(li->li_tv.vval.v_string, "$") == 0)
21001 	    pos.col = len + 1;
21002 
21003 	/* Accept a position up to the NUL after the line. */
21004 	if (pos.col == 0 || (int)pos.col > len + 1)
21005 	    return NULL;	/* invalid column number */
21006 	--pos.col;
21007 
21008 #ifdef FEAT_VIRTUALEDIT
21009 	/* Get the virtual offset.  Defaults to zero. */
21010 	pos.coladd = list_find_nr(l, 2L, &error);
21011 	if (error)
21012 	    pos.coladd = 0;
21013 #endif
21014 
21015 	return &pos;
21016     }
21017 
21018     name = get_tv_string_chk(varp);
21019     if (name == NULL)
21020 	return NULL;
21021     if (name[0] == '.')				/* cursor */
21022 	return &curwin->w_cursor;
21023     if (name[0] == 'v' && name[1] == NUL)	/* Visual start */
21024     {
21025 	if (VIsual_active)
21026 	    return &VIsual;
21027 	return &curwin->w_cursor;
21028     }
21029     if (name[0] == '\'')			/* mark */
21030     {
21031 	pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum);
21032 	if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
21033 	    return NULL;
21034 	return pp;
21035     }
21036 
21037 #ifdef FEAT_VIRTUALEDIT
21038     pos.coladd = 0;
21039 #endif
21040 
21041     if (name[0] == 'w' && dollar_lnum)
21042     {
21043 	pos.col = 0;
21044 	if (name[1] == '0')		/* "w0": first visible line */
21045 	{
21046 	    update_topline();
21047 	    pos.lnum = curwin->w_topline;
21048 	    return &pos;
21049 	}
21050 	else if (name[1] == '$')	/* "w$": last visible line */
21051 	{
21052 	    validate_botline();
21053 	    pos.lnum = curwin->w_botline - 1;
21054 	    return &pos;
21055 	}
21056     }
21057     else if (name[0] == '$')		/* last column or line */
21058     {
21059 	if (dollar_lnum)
21060 	{
21061 	    pos.lnum = curbuf->b_ml.ml_line_count;
21062 	    pos.col = 0;
21063 	}
21064 	else
21065 	{
21066 	    pos.lnum = curwin->w_cursor.lnum;
21067 	    pos.col = (colnr_T)STRLEN(ml_get_curline());
21068 	}
21069 	return &pos;
21070     }
21071     return NULL;
21072 }
21073 
21074 /*
21075  * Convert list in "arg" into a position and optional file number.
21076  * When "fnump" is NULL there is no file number, only 3 items.
21077  * Note that the column is passed on as-is, the caller may want to decrement
21078  * it to use 1 for the first column.
21079  * Return FAIL when conversion is not possible, doesn't check the position for
21080  * validity.
21081  */
21082     static int
21083 list2fpos(
21084     typval_T	*arg,
21085     pos_T	*posp,
21086     int		*fnump,
21087     colnr_T	*curswantp)
21088 {
21089     list_T	*l = arg->vval.v_list;
21090     long	i = 0;
21091     long	n;
21092 
21093     /* List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only
21094      * there when "fnump" isn't NULL; "coladd" and "curswant" are optional. */
21095     if (arg->v_type != VAR_LIST
21096 	    || l == NULL
21097 	    || l->lv_len < (fnump == NULL ? 2 : 3)
21098 	    || l->lv_len > (fnump == NULL ? 4 : 5))
21099 	return FAIL;
21100 
21101     if (fnump != NULL)
21102     {
21103 	n = list_find_nr(l, i++, NULL);	/* fnum */
21104 	if (n < 0)
21105 	    return FAIL;
21106 	if (n == 0)
21107 	    n = curbuf->b_fnum;		/* current buffer */
21108 	*fnump = n;
21109     }
21110 
21111     n = list_find_nr(l, i++, NULL);	/* lnum */
21112     if (n < 0)
21113 	return FAIL;
21114     posp->lnum = n;
21115 
21116     n = list_find_nr(l, i++, NULL);	/* col */
21117     if (n < 0)
21118 	return FAIL;
21119     posp->col = n;
21120 
21121 #ifdef FEAT_VIRTUALEDIT
21122     n = list_find_nr(l, i, NULL);	/* off */
21123     if (n < 0)
21124 	posp->coladd = 0;
21125     else
21126 	posp->coladd = n;
21127 #endif
21128 
21129     if (curswantp != NULL)
21130 	*curswantp = list_find_nr(l, i + 1, NULL);  /* curswant */
21131 
21132     return OK;
21133 }
21134 
21135 /*
21136  * Get the length of an environment variable name.
21137  * Advance "arg" to the first character after the name.
21138  * Return 0 for error.
21139  */
21140     static int
21141 get_env_len(char_u **arg)
21142 {
21143     char_u	*p;
21144     int		len;
21145 
21146     for (p = *arg; vim_isIDc(*p); ++p)
21147 	;
21148     if (p == *arg)	    /* no name found */
21149 	return 0;
21150 
21151     len = (int)(p - *arg);
21152     *arg = p;
21153     return len;
21154 }
21155 
21156 /*
21157  * Get the length of the name of a function or internal variable.
21158  * "arg" is advanced to the first non-white character after the name.
21159  * Return 0 if something is wrong.
21160  */
21161     static int
21162 get_id_len(char_u **arg)
21163 {
21164     char_u	*p;
21165     int		len;
21166 
21167     /* Find the end of the name. */
21168     for (p = *arg; eval_isnamec(*p); ++p)
21169     {
21170 	if (*p == ':')
21171 	{
21172 	    /* "s:" is start of "s:var", but "n:" is not and can be used in
21173 	     * slice "[n:]".  Also "xx:" is not a namespace. */
21174 	    len = (int)(p - *arg);
21175 	    if ((len == 1 && vim_strchr(NAMESPACE_CHAR, **arg) == NULL)
21176 		    || len > 1)
21177 		break;
21178 	}
21179     }
21180     if (p == *arg)	    /* no name found */
21181 	return 0;
21182 
21183     len = (int)(p - *arg);
21184     *arg = skipwhite(p);
21185 
21186     return len;
21187 }
21188 
21189 /*
21190  * Get the length of the name of a variable or function.
21191  * Only the name is recognized, does not handle ".key" or "[idx]".
21192  * "arg" is advanced to the first non-white character after the name.
21193  * Return -1 if curly braces expansion failed.
21194  * Return 0 if something else is wrong.
21195  * If the name contains 'magic' {}'s, expand them and return the
21196  * expanded name in an allocated string via 'alias' - caller must free.
21197  */
21198     static int
21199 get_name_len(
21200     char_u	**arg,
21201     char_u	**alias,
21202     int		evaluate,
21203     int		verbose)
21204 {
21205     int		len;
21206     char_u	*p;
21207     char_u	*expr_start;
21208     char_u	*expr_end;
21209 
21210     *alias = NULL;  /* default to no alias */
21211 
21212     if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
21213 						  && (*arg)[2] == (int)KE_SNR)
21214     {
21215 	/* hard coded <SNR>, already translated */
21216 	*arg += 3;
21217 	return get_id_len(arg) + 3;
21218     }
21219     len = eval_fname_script(*arg);
21220     if (len > 0)
21221     {
21222 	/* literal "<SID>", "s:" or "<SNR>" */
21223 	*arg += len;
21224     }
21225 
21226     /*
21227      * Find the end of the name; check for {} construction.
21228      */
21229     p = find_name_end(*arg, &expr_start, &expr_end,
21230 					       len > 0 ? 0 : FNE_CHECK_START);
21231     if (expr_start != NULL)
21232     {
21233 	char_u	*temp_string;
21234 
21235 	if (!evaluate)
21236 	{
21237 	    len += (int)(p - *arg);
21238 	    *arg = skipwhite(p);
21239 	    return len;
21240 	}
21241 
21242 	/*
21243 	 * Include any <SID> etc in the expanded string:
21244 	 * Thus the -len here.
21245 	 */
21246 	temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
21247 	if (temp_string == NULL)
21248 	    return -1;
21249 	*alias = temp_string;
21250 	*arg = skipwhite(p);
21251 	return (int)STRLEN(temp_string);
21252     }
21253 
21254     len += get_id_len(arg);
21255     if (len == 0 && verbose)
21256 	EMSG2(_(e_invexpr2), *arg);
21257 
21258     return len;
21259 }
21260 
21261 /*
21262  * Find the end of a variable or function name, taking care of magic braces.
21263  * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the
21264  * start and end of the first magic braces item.
21265  * "flags" can have FNE_INCL_BR and FNE_CHECK_START.
21266  * Return a pointer to just after the name.  Equal to "arg" if there is no
21267  * valid name.
21268  */
21269     static char_u *
21270 find_name_end(
21271     char_u	*arg,
21272     char_u	**expr_start,
21273     char_u	**expr_end,
21274     int		flags)
21275 {
21276     int		mb_nest = 0;
21277     int		br_nest = 0;
21278     char_u	*p;
21279     int		len;
21280 
21281     if (expr_start != NULL)
21282     {
21283 	*expr_start = NULL;
21284 	*expr_end = NULL;
21285     }
21286 
21287     /* Quick check for valid starting character. */
21288     if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{')
21289 	return arg;
21290 
21291     for (p = arg; *p != NUL
21292 		    && (eval_isnamec(*p)
21293 			|| *p == '{'
21294 			|| ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.'))
21295 			|| mb_nest != 0
21296 			|| br_nest != 0); mb_ptr_adv(p))
21297     {
21298 	if (*p == '\'')
21299 	{
21300 	    /* skip over 'string' to avoid counting [ and ] inside it. */
21301 	    for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p))
21302 		;
21303 	    if (*p == NUL)
21304 		break;
21305 	}
21306 	else if (*p == '"')
21307 	{
21308 	    /* skip over "str\"ing" to avoid counting [ and ] inside it. */
21309 	    for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p))
21310 		if (*p == '\\' && p[1] != NUL)
21311 		    ++p;
21312 	    if (*p == NUL)
21313 		break;
21314 	}
21315 	else if (br_nest == 0 && mb_nest == 0 && *p == ':')
21316 	{
21317 	    /* "s:" is start of "s:var", but "n:" is not and can be used in
21318 	     * slice "[n:]".  Also "xx:" is not a namespace. But {ns}: is. */
21319 	    len = (int)(p - arg);
21320 	    if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL)
21321 		    || (len > 1 && p[-1] != '}'))
21322 		break;
21323 	}
21324 
21325 	if (mb_nest == 0)
21326 	{
21327 	    if (*p == '[')
21328 		++br_nest;
21329 	    else if (*p == ']')
21330 		--br_nest;
21331 	}
21332 
21333 	if (br_nest == 0)
21334 	{
21335 	    if (*p == '{')
21336 	    {
21337 		mb_nest++;
21338 		if (expr_start != NULL && *expr_start == NULL)
21339 		    *expr_start = p;
21340 	    }
21341 	    else if (*p == '}')
21342 	    {
21343 		mb_nest--;
21344 		if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL)
21345 		    *expr_end = p;
21346 	    }
21347 	}
21348     }
21349 
21350     return p;
21351 }
21352 
21353 /*
21354  * Expands out the 'magic' {}'s in a variable/function name.
21355  * Note that this can call itself recursively, to deal with
21356  * constructs like foo{bar}{baz}{bam}
21357  * The four pointer arguments point to "foo{expre}ss{ion}bar"
21358  *			"in_start"      ^
21359  *			"expr_start"	   ^
21360  *			"expr_end"		 ^
21361  *			"in_end"			    ^
21362  *
21363  * Returns a new allocated string, which the caller must free.
21364  * Returns NULL for failure.
21365  */
21366     static char_u *
21367 make_expanded_name(
21368     char_u	*in_start,
21369     char_u	*expr_start,
21370     char_u	*expr_end,
21371     char_u	*in_end)
21372 {
21373     char_u	c1;
21374     char_u	*retval = NULL;
21375     char_u	*temp_result;
21376     char_u	*nextcmd = NULL;
21377 
21378     if (expr_end == NULL || in_end == NULL)
21379 	return NULL;
21380     *expr_start	= NUL;
21381     *expr_end = NUL;
21382     c1 = *in_end;
21383     *in_end = NUL;
21384 
21385     temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE);
21386     if (temp_result != NULL && nextcmd == NULL)
21387     {
21388 	retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start)
21389 						   + (in_end - expr_end) + 1));
21390 	if (retval != NULL)
21391 	{
21392 	    STRCPY(retval, in_start);
21393 	    STRCAT(retval, temp_result);
21394 	    STRCAT(retval, expr_end + 1);
21395 	}
21396     }
21397     vim_free(temp_result);
21398 
21399     *in_end = c1;		/* put char back for error messages */
21400     *expr_start = '{';
21401     *expr_end = '}';
21402 
21403     if (retval != NULL)
21404     {
21405 	temp_result = find_name_end(retval, &expr_start, &expr_end, 0);
21406 	if (expr_start != NULL)
21407 	{
21408 	    /* Further expansion! */
21409 	    temp_result = make_expanded_name(retval, expr_start,
21410 						       expr_end, temp_result);
21411 	    vim_free(retval);
21412 	    retval = temp_result;
21413 	}
21414     }
21415 
21416     return retval;
21417 }
21418 
21419 /*
21420  * Return TRUE if character "c" can be used in a variable or function name.
21421  * Does not include '{' or '}' for magic braces.
21422  */
21423     static int
21424 eval_isnamec(int c)
21425 {
21426     return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR);
21427 }
21428 
21429 /*
21430  * Return TRUE if character "c" can be used as the first character in a
21431  * variable or function name (excluding '{' and '}').
21432  */
21433     static int
21434 eval_isnamec1(int c)
21435 {
21436     return (ASCII_ISALPHA(c) || c == '_');
21437 }
21438 
21439 /*
21440  * Set number v: variable to "val".
21441  */
21442     void
21443 set_vim_var_nr(int idx, long val)
21444 {
21445     vimvars[idx].vv_nr = val;
21446 }
21447 
21448 /*
21449  * Get number v: variable value.
21450  */
21451     long
21452 get_vim_var_nr(int idx)
21453 {
21454     return vimvars[idx].vv_nr;
21455 }
21456 
21457 /*
21458  * Get string v: variable value.  Uses a static buffer, can only be used once.
21459  */
21460     char_u *
21461 get_vim_var_str(int idx)
21462 {
21463     return get_tv_string(&vimvars[idx].vv_tv);
21464 }
21465 
21466 /*
21467  * Get List v: variable value.  Caller must take care of reference count when
21468  * needed.
21469  */
21470     list_T *
21471 get_vim_var_list(int idx)
21472 {
21473     return vimvars[idx].vv_list;
21474 }
21475 
21476 /*
21477  * Set v:char to character "c".
21478  */
21479     void
21480 set_vim_var_char(int c)
21481 {
21482     char_u	buf[MB_MAXBYTES + 1];
21483 
21484 #ifdef FEAT_MBYTE
21485     if (has_mbyte)
21486 	buf[(*mb_char2bytes)(c, buf)] = NUL;
21487     else
21488 #endif
21489     {
21490 	buf[0] = c;
21491 	buf[1] = NUL;
21492     }
21493     set_vim_var_string(VV_CHAR, buf, -1);
21494 }
21495 
21496 /*
21497  * Set v:count to "count" and v:count1 to "count1".
21498  * When "set_prevcount" is TRUE first set v:prevcount from v:count.
21499  */
21500     void
21501 set_vcount(
21502     long	count,
21503     long	count1,
21504     int		set_prevcount)
21505 {
21506     if (set_prevcount)
21507 	vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
21508     vimvars[VV_COUNT].vv_nr = count;
21509     vimvars[VV_COUNT1].vv_nr = count1;
21510 }
21511 
21512 /*
21513  * Set string v: variable to a copy of "val".
21514  */
21515     void
21516 set_vim_var_string(
21517     int		idx,
21518     char_u	*val,
21519     int		len)	    /* length of "val" to use or -1 (whole string) */
21520 {
21521     clear_tv(&vimvars[idx].vv_di.di_tv);
21522     vimvars[idx].vv_type = VAR_STRING;
21523     if (val == NULL)
21524 	vimvars[idx].vv_str = NULL;
21525     else if (len == -1)
21526 	vimvars[idx].vv_str = vim_strsave(val);
21527     else
21528 	vimvars[idx].vv_str = vim_strnsave(val, len);
21529 }
21530 
21531 /*
21532  * Set List v: variable to "val".
21533  */
21534     void
21535 set_vim_var_list(int idx, list_T *val)
21536 {
21537     clear_tv(&vimvars[idx].vv_di.di_tv);
21538     vimvars[idx].vv_type = VAR_LIST;
21539     vimvars[idx].vv_list = val;
21540     if (val != NULL)
21541 	++val->lv_refcount;
21542 }
21543 
21544 /*
21545  * Set Dictionary v: variable to "val".
21546  */
21547     void
21548 set_vim_var_dict(int idx, dict_T *val)
21549 {
21550     int		todo;
21551     hashitem_T	*hi;
21552 
21553     clear_tv(&vimvars[idx].vv_di.di_tv);
21554     vimvars[idx].vv_type = VAR_DICT;
21555     vimvars[idx].vv_dict = val;
21556     if (val != NULL)
21557     {
21558 	++val->dv_refcount;
21559 
21560 	/* Set readonly */
21561 	todo = (int)val->dv_hashtab.ht_used;
21562 	for (hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi)
21563 	{
21564 	    if (HASHITEM_EMPTY(hi))
21565 		continue;
21566 	    --todo;
21567 	    HI2DI(hi)->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
21568 	}
21569     }
21570 }
21571 
21572 /*
21573  * Set v:register if needed.
21574  */
21575     void
21576 set_reg_var(int c)
21577 {
21578     char_u	regname;
21579 
21580     if (c == 0 || c == ' ')
21581 	regname = '"';
21582     else
21583 	regname = c;
21584     /* Avoid free/alloc when the value is already right. */
21585     if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c)
21586 	set_vim_var_string(VV_REG, &regname, 1);
21587 }
21588 
21589 /*
21590  * Get or set v:exception.  If "oldval" == NULL, return the current value.
21591  * Otherwise, restore the value to "oldval" and return NULL.
21592  * Must always be called in pairs to save and restore v:exception!  Does not
21593  * take care of memory allocations.
21594  */
21595     char_u *
21596 v_exception(char_u *oldval)
21597 {
21598     if (oldval == NULL)
21599 	return vimvars[VV_EXCEPTION].vv_str;
21600 
21601     vimvars[VV_EXCEPTION].vv_str = oldval;
21602     return NULL;
21603 }
21604 
21605 /*
21606  * Get or set v:throwpoint.  If "oldval" == NULL, return the current value.
21607  * Otherwise, restore the value to "oldval" and return NULL.
21608  * Must always be called in pairs to save and restore v:throwpoint!  Does not
21609  * take care of memory allocations.
21610  */
21611     char_u *
21612 v_throwpoint(char_u *oldval)
21613 {
21614     if (oldval == NULL)
21615 	return vimvars[VV_THROWPOINT].vv_str;
21616 
21617     vimvars[VV_THROWPOINT].vv_str = oldval;
21618     return NULL;
21619 }
21620 
21621 #if defined(FEAT_AUTOCMD) || defined(PROTO)
21622 /*
21623  * Set v:cmdarg.
21624  * If "eap" != NULL, use "eap" to generate the value and return the old value.
21625  * If "oldarg" != NULL, restore the value to "oldarg" and return NULL.
21626  * Must always be called in pairs!
21627  */
21628     char_u *
21629 set_cmdarg(exarg_T *eap, char_u *oldarg)
21630 {
21631     char_u	*oldval;
21632     char_u	*newval;
21633     unsigned	len;
21634 
21635     oldval = vimvars[VV_CMDARG].vv_str;
21636     if (eap == NULL)
21637     {
21638 	vim_free(oldval);
21639 	vimvars[VV_CMDARG].vv_str = oldarg;
21640 	return NULL;
21641     }
21642 
21643     if (eap->force_bin == FORCE_BIN)
21644 	len = 6;
21645     else if (eap->force_bin == FORCE_NOBIN)
21646 	len = 8;
21647     else
21648 	len = 0;
21649 
21650     if (eap->read_edit)
21651 	len += 7;
21652 
21653     if (eap->force_ff != 0)
21654 	len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
21655 # ifdef FEAT_MBYTE
21656     if (eap->force_enc != 0)
21657 	len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
21658     if (eap->bad_char != 0)
21659 	len += 7 + 4;  /* " ++bad=" + "keep" or "drop" */
21660 # endif
21661 
21662     newval = alloc(len + 1);
21663     if (newval == NULL)
21664 	return NULL;
21665 
21666     if (eap->force_bin == FORCE_BIN)
21667 	sprintf((char *)newval, " ++bin");
21668     else if (eap->force_bin == FORCE_NOBIN)
21669 	sprintf((char *)newval, " ++nobin");
21670     else
21671 	*newval = NUL;
21672 
21673     if (eap->read_edit)
21674 	STRCAT(newval, " ++edit");
21675 
21676     if (eap->force_ff != 0)
21677 	sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
21678 						eap->cmd + eap->force_ff);
21679 # ifdef FEAT_MBYTE
21680     if (eap->force_enc != 0)
21681 	sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
21682 					       eap->cmd + eap->force_enc);
21683     if (eap->bad_char == BAD_KEEP)
21684 	STRCPY(newval + STRLEN(newval), " ++bad=keep");
21685     else if (eap->bad_char == BAD_DROP)
21686 	STRCPY(newval + STRLEN(newval), " ++bad=drop");
21687     else if (eap->bad_char != 0)
21688 	sprintf((char *)newval + STRLEN(newval), " ++bad=%c", eap->bad_char);
21689 # endif
21690     vimvars[VV_CMDARG].vv_str = newval;
21691     return oldval;
21692 }
21693 #endif
21694 
21695 /*
21696  * Get the value of internal variable "name".
21697  * Return OK or FAIL.
21698  */
21699     static int
21700 get_var_tv(
21701     char_u	*name,
21702     int		len,		/* length of "name" */
21703     typval_T	*rettv,		/* NULL when only checking existence */
21704     dictitem_T	**dip,		/* non-NULL when typval's dict item is needed */
21705     int		verbose,	/* may give error message */
21706     int		no_autoload)	/* do not use script autoloading */
21707 {
21708     int		ret = OK;
21709     typval_T	*tv = NULL;
21710     typval_T	atv;
21711     dictitem_T	*v;
21712     int		cc;
21713 
21714     /* truncate the name, so that we can use strcmp() */
21715     cc = name[len];
21716     name[len] = NUL;
21717 
21718     /*
21719      * Check for "b:changedtick".
21720      */
21721     if (STRCMP(name, "b:changedtick") == 0)
21722     {
21723 	atv.v_type = VAR_NUMBER;
21724 	atv.vval.v_number = curbuf->b_changedtick;
21725 	tv = &atv;
21726     }
21727 
21728     /*
21729      * Check for user-defined variables.
21730      */
21731     else
21732     {
21733 	v = find_var(name, NULL, no_autoload);
21734 	if (v != NULL)
21735 	{
21736 	    tv = &v->di_tv;
21737 	    if (dip != NULL)
21738 		*dip = v;
21739 	}
21740     }
21741 
21742     if (tv == NULL)
21743     {
21744 	if (rettv != NULL && verbose)
21745 	    EMSG2(_(e_undefvar), name);
21746 	ret = FAIL;
21747     }
21748     else if (rettv != NULL)
21749 	copy_tv(tv, rettv);
21750 
21751     name[len] = cc;
21752 
21753     return ret;
21754 }
21755 
21756 /*
21757  * Handle expr[expr], expr[expr:expr] subscript and .name lookup.
21758  * Also handle function call with Funcref variable: func(expr)
21759  * Can all be combined: dict.func(expr)[idx]['func'](expr)
21760  */
21761     static int
21762 handle_subscript(
21763     char_u	**arg,
21764     typval_T	*rettv,
21765     int		evaluate,	/* do more than finding the end */
21766     int		verbose)	/* give error messages */
21767 {
21768     int		ret = OK;
21769     dict_T	*selfdict = NULL;
21770     char_u	*s;
21771     int		len;
21772     typval_T	functv;
21773 
21774     while (ret == OK
21775 	    && (**arg == '['
21776 		|| (**arg == '.' && rettv->v_type == VAR_DICT)
21777 		|| (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
21778 					    || rettv->v_type == VAR_PARTIAL)))
21779 	    && !vim_iswhite(*(*arg - 1)))
21780     {
21781 	if (**arg == '(')
21782 	{
21783 	    partial_T	*pt = NULL;
21784 
21785 	    /* need to copy the funcref so that we can clear rettv */
21786 	    if (evaluate)
21787 	    {
21788 		functv = *rettv;
21789 		rettv->v_type = VAR_UNKNOWN;
21790 
21791 		/* Invoke the function.  Recursive! */
21792 		if (functv.v_type == VAR_PARTIAL)
21793 		{
21794 		    pt = functv.vval.v_partial;
21795 		    s = pt->pt_name;
21796 		}
21797 		else
21798 		    s = functv.vval.v_string;
21799 	    }
21800 	    else
21801 		s = (char_u *)"";
21802 	    ret = get_func_tv(s, (int)STRLEN(s), rettv, arg,
21803 			curwin->w_cursor.lnum, curwin->w_cursor.lnum,
21804 			&len, evaluate, pt, selfdict);
21805 
21806 	    /* Clear the funcref afterwards, so that deleting it while
21807 	     * evaluating the arguments is possible (see test55). */
21808 	    if (evaluate)
21809 		clear_tv(&functv);
21810 
21811 	    /* Stop the expression evaluation when immediately aborting on
21812 	     * error, or when an interrupt occurred or an exception was thrown
21813 	     * but not caught. */
21814 	    if (aborting())
21815 	    {
21816 		if (ret == OK)
21817 		    clear_tv(rettv);
21818 		ret = FAIL;
21819 	    }
21820 	    dict_unref(selfdict);
21821 	    selfdict = NULL;
21822 	}
21823 	else /* **arg == '[' || **arg == '.' */
21824 	{
21825 	    dict_unref(selfdict);
21826 	    if (rettv->v_type == VAR_DICT)
21827 	    {
21828 		selfdict = rettv->vval.v_dict;
21829 		if (selfdict != NULL)
21830 		    ++selfdict->dv_refcount;
21831 	    }
21832 	    else
21833 		selfdict = NULL;
21834 	    if (eval_index(arg, rettv, evaluate, verbose) == FAIL)
21835 	    {
21836 		clear_tv(rettv);
21837 		ret = FAIL;
21838 	    }
21839 	}
21840     }
21841 
21842     if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL)
21843 							  && selfdict != NULL)
21844     {
21845 	char_u	    *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
21846 					     : rettv->vval.v_partial->pt_name;
21847 	char_u	    *tofree = NULL;
21848 	ufunc_T	    *fp;
21849 	char_u	    fname_buf[FLEN_FIXED + 1];
21850 	int	    error;
21851 
21852 	/* Translate "s:func" to the stored function name. */
21853 	fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
21854 	fp = find_func(fname);
21855 	vim_free(tofree);
21856 
21857 	/* Turn "dict.Func" into a partial for "Func" with "dict". */
21858 	if (fp != NULL && (fp->uf_flags & FC_DICT))
21859 	{
21860 	    partial_T	*pt = (partial_T *)alloc_clear(sizeof(partial_T));
21861 
21862 	    if (pt != NULL)
21863 	    {
21864 		pt->pt_refcount = 1;
21865 		pt->pt_dict = selfdict;
21866 		selfdict = NULL;
21867 		if (rettv->v_type == VAR_FUNC)
21868 		{
21869 		    /* Just a function: Take over the function name and use
21870 		     * selfdict. */
21871 		    pt->pt_name = rettv->vval.v_string;
21872 		}
21873 		else
21874 		{
21875 		    partial_T	*ret_pt = rettv->vval.v_partial;
21876 		    int		i;
21877 
21878 		    /* Partial: copy the function name, use selfdict and copy
21879 		     * args.  Can't take over name or args, the partial might
21880 		     * be referenced elsewhere. */
21881 		    pt->pt_name = vim_strsave(ret_pt->pt_name);
21882 		    func_ref(pt->pt_name);
21883 		    if (ret_pt->pt_argc > 0)
21884 		    {
21885 			pt->pt_argv = (typval_T *)alloc(
21886 					  sizeof(typval_T) * ret_pt->pt_argc);
21887 			if (pt->pt_argv == NULL)
21888 			    /* out of memory: drop the arguments */
21889 			    pt->pt_argc = 0;
21890 			else
21891 			{
21892 			    pt->pt_argc = ret_pt->pt_argc;
21893 			    for (i = 0; i < pt->pt_argc; i++)
21894 				copy_tv(&ret_pt->pt_argv[i], &pt->pt_argv[i]);
21895 			}
21896 		    }
21897 		    partial_unref(ret_pt);
21898 		}
21899 		rettv->v_type = VAR_PARTIAL;
21900 		rettv->vval.v_partial = pt;
21901 	    }
21902 	}
21903     }
21904 
21905     dict_unref(selfdict);
21906     return ret;
21907 }
21908 
21909 /*
21910  * Allocate memory for a variable type-value, and make it empty (0 or NULL
21911  * value).
21912  */
21913     typval_T *
21914 alloc_tv(void)
21915 {
21916     return (typval_T *)alloc_clear((unsigned)sizeof(typval_T));
21917 }
21918 
21919 /*
21920  * Allocate memory for a variable type-value, and assign a string to it.
21921  * The string "s" must have been allocated, it is consumed.
21922  * Return NULL for out of memory, the variable otherwise.
21923  */
21924     static typval_T *
21925 alloc_string_tv(char_u *s)
21926 {
21927     typval_T	*rettv;
21928 
21929     rettv = alloc_tv();
21930     if (rettv != NULL)
21931     {
21932 	rettv->v_type = VAR_STRING;
21933 	rettv->vval.v_string = s;
21934     }
21935     else
21936 	vim_free(s);
21937     return rettv;
21938 }
21939 
21940 /*
21941  * Free the memory for a variable type-value.
21942  */
21943     void
21944 free_tv(typval_T *varp)
21945 {
21946     if (varp != NULL)
21947     {
21948 	switch (varp->v_type)
21949 	{
21950 	    case VAR_FUNC:
21951 		func_unref(varp->vval.v_string);
21952 		/*FALLTHROUGH*/
21953 	    case VAR_STRING:
21954 		vim_free(varp->vval.v_string);
21955 		break;
21956 	    case VAR_PARTIAL:
21957 		partial_unref(varp->vval.v_partial);
21958 		break;
21959 	    case VAR_LIST:
21960 		list_unref(varp->vval.v_list);
21961 		break;
21962 	    case VAR_DICT:
21963 		dict_unref(varp->vval.v_dict);
21964 		break;
21965 	    case VAR_JOB:
21966 #ifdef FEAT_JOB_CHANNEL
21967 		job_unref(varp->vval.v_job);
21968 		break;
21969 #endif
21970 	    case VAR_CHANNEL:
21971 #ifdef FEAT_JOB_CHANNEL
21972 		channel_unref(varp->vval.v_channel);
21973 		break;
21974 #endif
21975 	    case VAR_NUMBER:
21976 	    case VAR_FLOAT:
21977 	    case VAR_UNKNOWN:
21978 	    case VAR_SPECIAL:
21979 		break;
21980 	}
21981 	vim_free(varp);
21982     }
21983 }
21984 
21985 /*
21986  * Free the memory for a variable value and set the value to NULL or 0.
21987  */
21988     void
21989 clear_tv(typval_T *varp)
21990 {
21991     if (varp != NULL)
21992     {
21993 	switch (varp->v_type)
21994 	{
21995 	    case VAR_FUNC:
21996 		func_unref(varp->vval.v_string);
21997 		/*FALLTHROUGH*/
21998 	    case VAR_STRING:
21999 		vim_free(varp->vval.v_string);
22000 		varp->vval.v_string = NULL;
22001 		break;
22002 	    case VAR_PARTIAL:
22003 		partial_unref(varp->vval.v_partial);
22004 		varp->vval.v_partial = NULL;
22005 		break;
22006 	    case VAR_LIST:
22007 		list_unref(varp->vval.v_list);
22008 		varp->vval.v_list = NULL;
22009 		break;
22010 	    case VAR_DICT:
22011 		dict_unref(varp->vval.v_dict);
22012 		varp->vval.v_dict = NULL;
22013 		break;
22014 	    case VAR_NUMBER:
22015 	    case VAR_SPECIAL:
22016 		varp->vval.v_number = 0;
22017 		break;
22018 	    case VAR_FLOAT:
22019 #ifdef FEAT_FLOAT
22020 		varp->vval.v_float = 0.0;
22021 		break;
22022 #endif
22023 	    case VAR_JOB:
22024 #ifdef FEAT_JOB_CHANNEL
22025 		job_unref(varp->vval.v_job);
22026 		varp->vval.v_job = NULL;
22027 #endif
22028 		break;
22029 	    case VAR_CHANNEL:
22030 #ifdef FEAT_JOB_CHANNEL
22031 		channel_unref(varp->vval.v_channel);
22032 		varp->vval.v_channel = NULL;
22033 #endif
22034 	    case VAR_UNKNOWN:
22035 		break;
22036 	}
22037 	varp->v_lock = 0;
22038     }
22039 }
22040 
22041 /*
22042  * Set the value of a variable to NULL without freeing items.
22043  */
22044     static void
22045 init_tv(typval_T *varp)
22046 {
22047     if (varp != NULL)
22048 	vim_memset(varp, 0, sizeof(typval_T));
22049 }
22050 
22051 /*
22052  * Get the number value of a variable.
22053  * If it is a String variable, uses vim_str2nr().
22054  * For incompatible types, return 0.
22055  * get_tv_number_chk() is similar to get_tv_number(), but informs the
22056  * caller of incompatible types: it sets *denote to TRUE if "denote"
22057  * is not NULL or returns -1 otherwise.
22058  */
22059     long
22060 get_tv_number(typval_T *varp)
22061 {
22062     int		error = FALSE;
22063 
22064     return get_tv_number_chk(varp, &error);	/* return 0L on error */
22065 }
22066 
22067     long
22068 get_tv_number_chk(typval_T *varp, int *denote)
22069 {
22070     long	n = 0L;
22071 
22072     switch (varp->v_type)
22073     {
22074 	case VAR_NUMBER:
22075 	    return (long)(varp->vval.v_number);
22076 	case VAR_FLOAT:
22077 #ifdef FEAT_FLOAT
22078 	    EMSG(_("E805: Using a Float as a Number"));
22079 	    break;
22080 #endif
22081 	case VAR_FUNC:
22082 	case VAR_PARTIAL:
22083 	    EMSG(_("E703: Using a Funcref as a Number"));
22084 	    break;
22085 	case VAR_STRING:
22086 	    if (varp->vval.v_string != NULL)
22087 		vim_str2nr(varp->vval.v_string, NULL, NULL,
22088 						    STR2NR_ALL, &n, NULL, 0);
22089 	    return n;
22090 	case VAR_LIST:
22091 	    EMSG(_("E745: Using a List as a Number"));
22092 	    break;
22093 	case VAR_DICT:
22094 	    EMSG(_("E728: Using a Dictionary as a Number"));
22095 	    break;
22096 	case VAR_SPECIAL:
22097 	    return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
22098 	    break;
22099 	case VAR_JOB:
22100 #ifdef FEAT_JOB_CHANNEL
22101 	    EMSG(_("E910: Using a Job as a Number"));
22102 	    break;
22103 #endif
22104 	case VAR_CHANNEL:
22105 #ifdef FEAT_JOB_CHANNEL
22106 	    EMSG(_("E913: Using a Channel as a Number"));
22107 	    break;
22108 #endif
22109 	case VAR_UNKNOWN:
22110 	    EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)");
22111 	    break;
22112     }
22113     if (denote == NULL)		/* useful for values that must be unsigned */
22114 	n = -1;
22115     else
22116 	*denote = TRUE;
22117     return n;
22118 }
22119 
22120 #ifdef FEAT_FLOAT
22121     static float_T
22122 get_tv_float(typval_T *varp)
22123 {
22124     switch (varp->v_type)
22125     {
22126 	case VAR_NUMBER:
22127 	    return (float_T)(varp->vval.v_number);
22128 	case VAR_FLOAT:
22129 	    return varp->vval.v_float;
22130 	case VAR_FUNC:
22131 	case VAR_PARTIAL:
22132 	    EMSG(_("E891: Using a Funcref as a Float"));
22133 	    break;
22134 	case VAR_STRING:
22135 	    EMSG(_("E892: Using a String as a Float"));
22136 	    break;
22137 	case VAR_LIST:
22138 	    EMSG(_("E893: Using a List as a Float"));
22139 	    break;
22140 	case VAR_DICT:
22141 	    EMSG(_("E894: Using a Dictionary as a Float"));
22142 	    break;
22143 	case VAR_SPECIAL:
22144 	    EMSG(_("E907: Using a special value as a Float"));
22145 	    break;
22146 	case VAR_JOB:
22147 # ifdef FEAT_JOB_CHANNEL
22148 	    EMSG(_("E911: Using a Job as a Float"));
22149 	    break;
22150 # endif
22151 	case VAR_CHANNEL:
22152 # ifdef FEAT_JOB_CHANNEL
22153 	    EMSG(_("E914: Using a Channel as a Float"));
22154 	    break;
22155 # endif
22156 	case VAR_UNKNOWN:
22157 	    EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)");
22158 	    break;
22159     }
22160     return 0;
22161 }
22162 #endif
22163 
22164 /*
22165  * Get the lnum from the first argument.
22166  * Also accepts ".", "$", etc., but that only works for the current buffer.
22167  * Returns -1 on error.
22168  */
22169     static linenr_T
22170 get_tv_lnum(typval_T *argvars)
22171 {
22172     typval_T	rettv;
22173     linenr_T	lnum;
22174 
22175     lnum = get_tv_number_chk(&argvars[0], NULL);
22176     if (lnum == 0)  /* no valid number, try using line() */
22177     {
22178 	rettv.v_type = VAR_NUMBER;
22179 	f_line(argvars, &rettv);
22180 	lnum = rettv.vval.v_number;
22181 	clear_tv(&rettv);
22182     }
22183     return lnum;
22184 }
22185 
22186 /*
22187  * Get the lnum from the first argument.
22188  * Also accepts "$", then "buf" is used.
22189  * Returns 0 on error.
22190  */
22191     static linenr_T
22192 get_tv_lnum_buf(typval_T *argvars, buf_T *buf)
22193 {
22194     if (argvars[0].v_type == VAR_STRING
22195 	    && argvars[0].vval.v_string != NULL
22196 	    && argvars[0].vval.v_string[0] == '$'
22197 	    && buf != NULL)
22198 	return buf->b_ml.ml_line_count;
22199     return get_tv_number_chk(&argvars[0], NULL);
22200 }
22201 
22202 /*
22203  * Get the string value of a variable.
22204  * If it is a Number variable, the number is converted into a string.
22205  * get_tv_string() uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
22206  * get_tv_string_buf() uses a given buffer.
22207  * If the String variable has never been set, return an empty string.
22208  * Never returns NULL;
22209  * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return
22210  * NULL on error.
22211  */
22212     char_u *
22213 get_tv_string(typval_T *varp)
22214 {
22215     static char_u   mybuf[NUMBUFLEN];
22216 
22217     return get_tv_string_buf(varp, mybuf);
22218 }
22219 
22220     char_u *
22221 get_tv_string_buf(typval_T *varp, char_u *buf)
22222 {
22223     char_u	*res =  get_tv_string_buf_chk(varp, buf);
22224 
22225     return res != NULL ? res : (char_u *)"";
22226 }
22227 
22228 /*
22229  * Careful: This uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
22230  */
22231     char_u *
22232 get_tv_string_chk(typval_T *varp)
22233 {
22234     static char_u   mybuf[NUMBUFLEN];
22235 
22236     return get_tv_string_buf_chk(varp, mybuf);
22237 }
22238 
22239     char_u *
22240 get_tv_string_buf_chk(typval_T *varp, char_u *buf)
22241 {
22242     switch (varp->v_type)
22243     {
22244 	case VAR_NUMBER:
22245 	    sprintf((char *)buf, "%ld", (long)varp->vval.v_number);
22246 	    return buf;
22247 	case VAR_FUNC:
22248 	case VAR_PARTIAL:
22249 	    EMSG(_("E729: using Funcref as a String"));
22250 	    break;
22251 	case VAR_LIST:
22252 	    EMSG(_("E730: using List as a String"));
22253 	    break;
22254 	case VAR_DICT:
22255 	    EMSG(_("E731: using Dictionary as a String"));
22256 	    break;
22257 	case VAR_FLOAT:
22258 #ifdef FEAT_FLOAT
22259 	    EMSG(_(e_float_as_string));
22260 	    break;
22261 #endif
22262 	case VAR_STRING:
22263 	    if (varp->vval.v_string != NULL)
22264 		return varp->vval.v_string;
22265 	    return (char_u *)"";
22266 	case VAR_SPECIAL:
22267 	    STRCPY(buf, get_var_special_name(varp->vval.v_number));
22268 	    return buf;
22269 	case VAR_JOB:
22270 #ifdef FEAT_JOB_CHANNEL
22271 	    {
22272 		job_T *job = varp->vval.v_job;
22273 		char  *status;
22274 
22275 		if (job == NULL)
22276 		    return (char_u *)"no process";
22277 		status = job->jv_status == JOB_FAILED ? "fail"
22278 				: job->jv_status == JOB_ENDED ? "dead"
22279 				: "run";
22280 # ifdef UNIX
22281 		vim_snprintf((char *)buf, NUMBUFLEN,
22282 			    "process %ld %s", (long)job->jv_pid, status);
22283 # elif defined(WIN32)
22284 		vim_snprintf((char *)buf, NUMBUFLEN,
22285 			    "process %ld %s",
22286 			    (long)job->jv_proc_info.dwProcessId,
22287 			    status);
22288 # else
22289 		/* fall-back */
22290 		vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status);
22291 # endif
22292 		return buf;
22293 	    }
22294 #endif
22295 	    break;
22296 	case VAR_CHANNEL:
22297 #ifdef FEAT_JOB_CHANNEL
22298 	    {
22299 		channel_T *channel = varp->vval.v_channel;
22300 		char      *status = channel_status(channel);
22301 
22302 		if (channel == NULL)
22303 		    vim_snprintf((char *)buf, NUMBUFLEN, "channel %s", status);
22304 		else
22305 		    vim_snprintf((char *)buf, NUMBUFLEN,
22306 				     "channel %d %s", channel->ch_id, status);
22307 		return buf;
22308 	    }
22309 #endif
22310 	    break;
22311 	case VAR_UNKNOWN:
22312 	    EMSG(_("E908: using an invalid value as a String"));
22313 	    break;
22314     }
22315     return NULL;
22316 }
22317 
22318 /*
22319  * Find variable "name" in the list of variables.
22320  * Return a pointer to it if found, NULL if not found.
22321  * Careful: "a:0" variables don't have a name.
22322  * When "htp" is not NULL we are writing to the variable, set "htp" to the
22323  * hashtab_T used.
22324  */
22325     static dictitem_T *
22326 find_var(char_u *name, hashtab_T **htp, int no_autoload)
22327 {
22328     char_u	*varname;
22329     hashtab_T	*ht;
22330 
22331     ht = find_var_ht(name, &varname);
22332     if (htp != NULL)
22333 	*htp = ht;
22334     if (ht == NULL)
22335 	return NULL;
22336     return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL);
22337 }
22338 
22339 /*
22340  * Find variable "varname" in hashtab "ht" with name "htname".
22341  * Returns NULL if not found.
22342  */
22343     static dictitem_T *
22344 find_var_in_ht(
22345     hashtab_T	*ht,
22346     int		htname,
22347     char_u	*varname,
22348     int		no_autoload)
22349 {
22350     hashitem_T	*hi;
22351 
22352     if (*varname == NUL)
22353     {
22354 	/* Must be something like "s:", otherwise "ht" would be NULL. */
22355 	switch (htname)
22356 	{
22357 	    case 's': return &SCRIPT_SV(current_SID)->sv_var;
22358 	    case 'g': return &globvars_var;
22359 	    case 'v': return &vimvars_var;
22360 	    case 'b': return &curbuf->b_bufvar;
22361 	    case 'w': return &curwin->w_winvar;
22362 #ifdef FEAT_WINDOWS
22363 	    case 't': return &curtab->tp_winvar;
22364 #endif
22365 	    case 'l': return current_funccal == NULL
22366 					? NULL : &current_funccal->l_vars_var;
22367 	    case 'a': return current_funccal == NULL
22368 				       ? NULL : &current_funccal->l_avars_var;
22369 	}
22370 	return NULL;
22371     }
22372 
22373     hi = hash_find(ht, varname);
22374     if (HASHITEM_EMPTY(hi))
22375     {
22376 	/* For global variables we may try auto-loading the script.  If it
22377 	 * worked find the variable again.  Don't auto-load a script if it was
22378 	 * loaded already, otherwise it would be loaded every time when
22379 	 * checking if a function name is a Funcref variable. */
22380 	if (ht == &globvarht && !no_autoload)
22381 	{
22382 	    /* Note: script_autoload() may make "hi" invalid. It must either
22383 	     * be obtained again or not used. */
22384 	    if (!script_autoload(varname, FALSE) || aborting())
22385 		return NULL;
22386 	    hi = hash_find(ht, varname);
22387 	}
22388 	if (HASHITEM_EMPTY(hi))
22389 	    return NULL;
22390     }
22391     return HI2DI(hi);
22392 }
22393 
22394 /*
22395  * Find the hashtab used for a variable name.
22396  * Return NULL if the name is not valid.
22397  * Set "varname" to the start of name without ':'.
22398  */
22399     static hashtab_T *
22400 find_var_ht(char_u *name, char_u **varname)
22401 {
22402     hashitem_T	*hi;
22403 
22404     if (name[0] == NUL)
22405 	return NULL;
22406     if (name[1] != ':')
22407     {
22408 	/* The name must not start with a colon or #. */
22409 	if (name[0] == ':' || name[0] == AUTOLOAD_CHAR)
22410 	    return NULL;
22411 	*varname = name;
22412 
22413 	/* "version" is "v:version" in all scopes */
22414 	hi = hash_find(&compat_hashtab, name);
22415 	if (!HASHITEM_EMPTY(hi))
22416 	    return &compat_hashtab;
22417 
22418 	if (current_funccal == NULL)
22419 	    return &globvarht;			/* global variable */
22420 	return &get_funccal()->l_vars.dv_hashtab; /* l: variable */
22421     }
22422     *varname = name + 2;
22423     if (*name == 'g')				/* global variable */
22424 	return &globvarht;
22425     /* There must be no ':' or '#' in the rest of the name, unless g: is used
22426      */
22427     if (vim_strchr(name + 2, ':') != NULL
22428 			       || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL)
22429 	return NULL;
22430     if (*name == 'b')				/* buffer variable */
22431 	return &curbuf->b_vars->dv_hashtab;
22432     if (*name == 'w')				/* window variable */
22433 	return &curwin->w_vars->dv_hashtab;
22434 #ifdef FEAT_WINDOWS
22435     if (*name == 't')				/* tab page variable */
22436 	return &curtab->tp_vars->dv_hashtab;
22437 #endif
22438     if (*name == 'v')				/* v: variable */
22439 	return &vimvarht;
22440     if (*name == 'a' && current_funccal != NULL) /* function argument */
22441 	return &get_funccal()->l_avars.dv_hashtab;
22442     if (*name == 'l' && current_funccal != NULL) /* local function variable */
22443 	return &get_funccal()->l_vars.dv_hashtab;
22444     if (*name == 's'				/* script variable */
22445 	    && current_SID > 0 && current_SID <= ga_scripts.ga_len)
22446 	return &SCRIPT_VARS(current_SID);
22447     return NULL;
22448 }
22449 
22450 /*
22451  * Get function call environment based on bactrace debug level
22452  */
22453     static funccall_T *
22454 get_funccal(void)
22455 {
22456     int		i;
22457     funccall_T	*funccal;
22458     funccall_T	*temp_funccal;
22459 
22460     funccal = current_funccal;
22461     if (debug_backtrace_level > 0)
22462     {
22463 	for (i = 0; i < debug_backtrace_level; i++)
22464 	{
22465 	    temp_funccal = funccal->caller;
22466 	    if (temp_funccal)
22467 		funccal = temp_funccal;
22468 	    else
22469 		/* backtrace level overflow. reset to max */
22470 		debug_backtrace_level = i;
22471 	}
22472     }
22473     return funccal;
22474 }
22475 
22476 /*
22477  * Get the string value of a (global/local) variable.
22478  * Note: see get_tv_string() for how long the pointer remains valid.
22479  * Returns NULL when it doesn't exist.
22480  */
22481     char_u *
22482 get_var_value(char_u *name)
22483 {
22484     dictitem_T	*v;
22485 
22486     v = find_var(name, NULL, FALSE);
22487     if (v == NULL)
22488 	return NULL;
22489     return get_tv_string(&v->di_tv);
22490 }
22491 
22492 /*
22493  * Allocate a new hashtab for a sourced script.  It will be used while
22494  * sourcing this script and when executing functions defined in the script.
22495  */
22496     void
22497 new_script_vars(scid_T id)
22498 {
22499     int		i;
22500     hashtab_T	*ht;
22501     scriptvar_T *sv;
22502 
22503     if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
22504     {
22505 	/* Re-allocating ga_data means that an ht_array pointing to
22506 	 * ht_smallarray becomes invalid.  We can recognize this: ht_mask is
22507 	 * at its init value.  Also reset "v_dict", it's always the same. */
22508 	for (i = 1; i <= ga_scripts.ga_len; ++i)
22509 	{
22510 	    ht = &SCRIPT_VARS(i);
22511 	    if (ht->ht_mask == HT_INIT_SIZE - 1)
22512 		ht->ht_array = ht->ht_smallarray;
22513 	    sv = SCRIPT_SV(i);
22514 	    sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict;
22515 	}
22516 
22517 	while (ga_scripts.ga_len < id)
22518 	{
22519 	    sv = SCRIPT_SV(ga_scripts.ga_len + 1) =
22520 		(scriptvar_T *)alloc_clear(sizeof(scriptvar_T));
22521 	    init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
22522 	    ++ga_scripts.ga_len;
22523 	}
22524     }
22525 }
22526 
22527 /*
22528  * Initialize dictionary "dict" as a scope and set variable "dict_var" to
22529  * point to it.
22530  */
22531     void
22532 init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope)
22533 {
22534     hash_init(&dict->dv_hashtab);
22535     dict->dv_lock = 0;
22536     dict->dv_scope = scope;
22537     dict->dv_refcount = DO_NOT_FREE_CNT;
22538     dict->dv_copyID = 0;
22539     dict_var->di_tv.vval.v_dict = dict;
22540     dict_var->di_tv.v_type = VAR_DICT;
22541     dict_var->di_tv.v_lock = VAR_FIXED;
22542     dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
22543     dict_var->di_key[0] = NUL;
22544 }
22545 
22546 /*
22547  * Unreference a dictionary initialized by init_var_dict().
22548  */
22549     void
22550 unref_var_dict(dict_T *dict)
22551 {
22552     /* Now the dict needs to be freed if no one else is using it, go back to
22553      * normal reference counting. */
22554     dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
22555     dict_unref(dict);
22556 }
22557 
22558 /*
22559  * Clean up a list of internal variables.
22560  * Frees all allocated variables and the value they contain.
22561  * Clears hashtab "ht", does not free it.
22562  */
22563     void
22564 vars_clear(hashtab_T *ht)
22565 {
22566     vars_clear_ext(ht, TRUE);
22567 }
22568 
22569 /*
22570  * Like vars_clear(), but only free the value if "free_val" is TRUE.
22571  */
22572     static void
22573 vars_clear_ext(hashtab_T *ht, int free_val)
22574 {
22575     int		todo;
22576     hashitem_T	*hi;
22577     dictitem_T	*v;
22578 
22579     hash_lock(ht);
22580     todo = (int)ht->ht_used;
22581     for (hi = ht->ht_array; todo > 0; ++hi)
22582     {
22583 	if (!HASHITEM_EMPTY(hi))
22584 	{
22585 	    --todo;
22586 
22587 	    /* Free the variable.  Don't remove it from the hashtab,
22588 	     * ht_array might change then.  hash_clear() takes care of it
22589 	     * later. */
22590 	    v = HI2DI(hi);
22591 	    if (free_val)
22592 		clear_tv(&v->di_tv);
22593 	    if (v->di_flags & DI_FLAGS_ALLOC)
22594 		vim_free(v);
22595 	}
22596     }
22597     hash_clear(ht);
22598     ht->ht_used = 0;
22599 }
22600 
22601 /*
22602  * Delete a variable from hashtab "ht" at item "hi".
22603  * Clear the variable value and free the dictitem.
22604  */
22605     static void
22606 delete_var(hashtab_T *ht, hashitem_T *hi)
22607 {
22608     dictitem_T	*di = HI2DI(hi);
22609 
22610     hash_remove(ht, hi);
22611     clear_tv(&di->di_tv);
22612     vim_free(di);
22613 }
22614 
22615 /*
22616  * List the value of one internal variable.
22617  */
22618     static void
22619 list_one_var(dictitem_T *v, char_u *prefix, int *first)
22620 {
22621     char_u	*tofree;
22622     char_u	*s;
22623     char_u	numbuf[NUMBUFLEN];
22624 
22625     s = echo_string(&v->di_tv, &tofree, numbuf, get_copyID());
22626     list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
22627 					 s == NULL ? (char_u *)"" : s, first);
22628     vim_free(tofree);
22629 }
22630 
22631     static void
22632 list_one_var_a(
22633     char_u	*prefix,
22634     char_u	*name,
22635     int		type,
22636     char_u	*string,
22637     int		*first)  /* when TRUE clear rest of screen and set to FALSE */
22638 {
22639     /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */
22640     msg_start();
22641     msg_puts(prefix);
22642     if (name != NULL)	/* "a:" vars don't have a name stored */
22643 	msg_puts(name);
22644     msg_putchar(' ');
22645     msg_advance(22);
22646     if (type == VAR_NUMBER)
22647 	msg_putchar('#');
22648     else if (type == VAR_FUNC || type == VAR_PARTIAL)
22649 	msg_putchar('*');
22650     else if (type == VAR_LIST)
22651     {
22652 	msg_putchar('[');
22653 	if (*string == '[')
22654 	    ++string;
22655     }
22656     else if (type == VAR_DICT)
22657     {
22658 	msg_putchar('{');
22659 	if (*string == '{')
22660 	    ++string;
22661     }
22662     else
22663 	msg_putchar(' ');
22664 
22665     msg_outtrans(string);
22666 
22667     if (type == VAR_FUNC || type == VAR_PARTIAL)
22668 	msg_puts((char_u *)"()");
22669     if (*first)
22670     {
22671 	msg_clr_eos();
22672 	*first = FALSE;
22673     }
22674 }
22675 
22676 /*
22677  * Set variable "name" to value in "tv".
22678  * If the variable already exists, the value is updated.
22679  * Otherwise the variable is created.
22680  */
22681     static void
22682 set_var(
22683     char_u	*name,
22684     typval_T	*tv,
22685     int		copy)	    /* make copy of value in "tv" */
22686 {
22687     dictitem_T	*v;
22688     char_u	*varname;
22689     hashtab_T	*ht;
22690 
22691     ht = find_var_ht(name, &varname);
22692     if (ht == NULL || *varname == NUL)
22693     {
22694 	EMSG2(_(e_illvar), name);
22695 	return;
22696     }
22697     v = find_var_in_ht(ht, 0, varname, TRUE);
22698 
22699     if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL)
22700 				      && var_check_func_name(name, v == NULL))
22701 	return;
22702 
22703     if (v != NULL)
22704     {
22705 	/* existing variable, need to clear the value */
22706 	if (var_check_ro(v->di_flags, name, FALSE)
22707 			       || tv_check_lock(v->di_tv.v_lock, name, FALSE))
22708 	    return;
22709 
22710 	/*
22711 	 * Handle setting internal v: variables separately where needed to
22712 	 * prevent changing the type.
22713 	 */
22714 	if (ht == &vimvarht)
22715 	{
22716 	    if (v->di_tv.v_type == VAR_STRING)
22717 	    {
22718 		vim_free(v->di_tv.vval.v_string);
22719 		if (copy || tv->v_type != VAR_STRING)
22720 		    v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv));
22721 		else
22722 		{
22723 		    /* Take over the string to avoid an extra alloc/free. */
22724 		    v->di_tv.vval.v_string = tv->vval.v_string;
22725 		    tv->vval.v_string = NULL;
22726 		}
22727 		return;
22728 	    }
22729 	    else if (v->di_tv.v_type == VAR_NUMBER)
22730 	    {
22731 		v->di_tv.vval.v_number = get_tv_number(tv);
22732 		if (STRCMP(varname, "searchforward") == 0)
22733 		    set_search_direction(v->di_tv.vval.v_number ? '/' : '?');
22734 #ifdef FEAT_SEARCH_EXTRA
22735 		else if (STRCMP(varname, "hlsearch") == 0)
22736 		{
22737 		    no_hlsearch = !v->di_tv.vval.v_number;
22738 		    redraw_all_later(SOME_VALID);
22739 		}
22740 #endif
22741 		return;
22742 	    }
22743 	    else if (v->di_tv.v_type != tv->v_type)
22744 		EMSG2(_(e_intern2), "set_var()");
22745 	}
22746 
22747 	clear_tv(&v->di_tv);
22748     }
22749     else		    /* add a new variable */
22750     {
22751 	/* Can't add "v:" variable. */
22752 	if (ht == &vimvarht)
22753 	{
22754 	    EMSG2(_(e_illvar), name);
22755 	    return;
22756 	}
22757 
22758 	/* Make sure the variable name is valid. */
22759 	if (!valid_varname(varname))
22760 	    return;
22761 
22762 	v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
22763 							  + STRLEN(varname)));
22764 	if (v == NULL)
22765 	    return;
22766 	STRCPY(v->di_key, varname);
22767 	if (hash_add(ht, DI2HIKEY(v)) == FAIL)
22768 	{
22769 	    vim_free(v);
22770 	    return;
22771 	}
22772 	v->di_flags = DI_FLAGS_ALLOC;
22773     }
22774 
22775     if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT)
22776 	copy_tv(tv, &v->di_tv);
22777     else
22778     {
22779 	v->di_tv = *tv;
22780 	v->di_tv.v_lock = 0;
22781 	init_tv(tv);
22782     }
22783 }
22784 
22785 /*
22786  * Return TRUE if di_flags "flags" indicates variable "name" is read-only.
22787  * Also give an error message.
22788  */
22789     static int
22790 var_check_ro(int flags, char_u *name, int use_gettext)
22791 {
22792     if (flags & DI_FLAGS_RO)
22793     {
22794 	EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name);
22795 	return TRUE;
22796     }
22797     if ((flags & DI_FLAGS_RO_SBX) && sandbox)
22798     {
22799 	EMSG2(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name);
22800 	return TRUE;
22801     }
22802     return FALSE;
22803 }
22804 
22805 /*
22806  * Return TRUE if di_flags "flags" indicates variable "name" is fixed.
22807  * Also give an error message.
22808  */
22809     static int
22810 var_check_fixed(int flags, char_u *name, int use_gettext)
22811 {
22812     if (flags & DI_FLAGS_FIX)
22813     {
22814 	EMSG2(_("E795: Cannot delete variable %s"),
22815 				      use_gettext ? (char_u *)_(name) : name);
22816 	return TRUE;
22817     }
22818     return FALSE;
22819 }
22820 
22821 /*
22822  * Check if a funcref is assigned to a valid variable name.
22823  * Return TRUE and give an error if not.
22824  */
22825     static int
22826 var_check_func_name(
22827     char_u *name,    /* points to start of variable name */
22828     int    new_var)  /* TRUE when creating the variable */
22829 {
22830     /* Allow for w: b: s: and t:. */
22831     if (!(vim_strchr((char_u *)"wbst", name[0]) != NULL && name[1] == ':')
22832 	    && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
22833 						     ? name[2] : name[0]))
22834     {
22835 	EMSG2(_("E704: Funcref variable name must start with a capital: %s"),
22836 									name);
22837 	return TRUE;
22838     }
22839     /* Don't allow hiding a function.  When "v" is not NULL we might be
22840      * assigning another function to the same var, the type is checked
22841      * below. */
22842     if (new_var && function_exists(name))
22843     {
22844 	EMSG2(_("E705: Variable name conflicts with existing function: %s"),
22845 								    name);
22846 	return TRUE;
22847     }
22848     return FALSE;
22849 }
22850 
22851 /*
22852  * Check if a variable name is valid.
22853  * Return FALSE and give an error if not.
22854  */
22855     static int
22856 valid_varname(char_u *varname)
22857 {
22858     char_u *p;
22859 
22860     for (p = varname; *p != NUL; ++p)
22861 	if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
22862 						   && *p != AUTOLOAD_CHAR)
22863 	{
22864 	    EMSG2(_(e_illvar), varname);
22865 	    return FALSE;
22866 	}
22867     return TRUE;
22868 }
22869 
22870 /*
22871  * Return TRUE if typeval "tv" is set to be locked (immutable).
22872  * Also give an error message, using "name" or _("name") when use_gettext is
22873  * TRUE.
22874  */
22875     static int
22876 tv_check_lock(int lock, char_u *name, int use_gettext)
22877 {
22878     if (lock & VAR_LOCKED)
22879     {
22880 	EMSG2(_("E741: Value is locked: %s"),
22881 				name == NULL ? (char_u *)_("Unknown")
22882 					     : use_gettext ? (char_u *)_(name)
22883 					     : name);
22884 	return TRUE;
22885     }
22886     if (lock & VAR_FIXED)
22887     {
22888 	EMSG2(_("E742: Cannot change value of %s"),
22889 				name == NULL ? (char_u *)_("Unknown")
22890 					     : use_gettext ? (char_u *)_(name)
22891 					     : name);
22892 	return TRUE;
22893     }
22894     return FALSE;
22895 }
22896 
22897 /*
22898  * Copy the values from typval_T "from" to typval_T "to".
22899  * When needed allocates string or increases reference count.
22900  * Does not make a copy of a list or dict but copies the reference!
22901  * It is OK for "from" and "to" to point to the same item.  This is used to
22902  * make a copy later.
22903  */
22904     void
22905 copy_tv(typval_T *from, typval_T *to)
22906 {
22907     to->v_type = from->v_type;
22908     to->v_lock = 0;
22909     switch (from->v_type)
22910     {
22911 	case VAR_NUMBER:
22912 	case VAR_SPECIAL:
22913 	    to->vval.v_number = from->vval.v_number;
22914 	    break;
22915 	case VAR_FLOAT:
22916 #ifdef FEAT_FLOAT
22917 	    to->vval.v_float = from->vval.v_float;
22918 	    break;
22919 #endif
22920 	case VAR_JOB:
22921 #ifdef FEAT_JOB_CHANNEL
22922 	    to->vval.v_job = from->vval.v_job;
22923 	    if (to->vval.v_job != NULL)
22924 		++to->vval.v_job->jv_refcount;
22925 	    break;
22926 #endif
22927 	case VAR_CHANNEL:
22928 #ifdef FEAT_JOB_CHANNEL
22929 	    to->vval.v_channel = from->vval.v_channel;
22930 	    if (to->vval.v_channel != NULL)
22931 		++to->vval.v_channel->ch_refcount;
22932 	    break;
22933 #endif
22934 	case VAR_STRING:
22935 	case VAR_FUNC:
22936 	    if (from->vval.v_string == NULL)
22937 		to->vval.v_string = NULL;
22938 	    else
22939 	    {
22940 		to->vval.v_string = vim_strsave(from->vval.v_string);
22941 		if (from->v_type == VAR_FUNC)
22942 		    func_ref(to->vval.v_string);
22943 	    }
22944 	    break;
22945 	case VAR_PARTIAL:
22946 	    if (from->vval.v_partial == NULL)
22947 		to->vval.v_partial = NULL;
22948 	    else
22949 	    {
22950 		to->vval.v_partial = from->vval.v_partial;
22951 		++to->vval.v_partial->pt_refcount;
22952 	    }
22953 	    break;
22954 	case VAR_LIST:
22955 	    if (from->vval.v_list == NULL)
22956 		to->vval.v_list = NULL;
22957 	    else
22958 	    {
22959 		to->vval.v_list = from->vval.v_list;
22960 		++to->vval.v_list->lv_refcount;
22961 	    }
22962 	    break;
22963 	case VAR_DICT:
22964 	    if (from->vval.v_dict == NULL)
22965 		to->vval.v_dict = NULL;
22966 	    else
22967 	    {
22968 		to->vval.v_dict = from->vval.v_dict;
22969 		++to->vval.v_dict->dv_refcount;
22970 	    }
22971 	    break;
22972 	case VAR_UNKNOWN:
22973 	    EMSG2(_(e_intern2), "copy_tv(UNKNOWN)");
22974 	    break;
22975     }
22976 }
22977 
22978 /*
22979  * Make a copy of an item.
22980  * Lists and Dictionaries are also copied.  A deep copy if "deep" is set.
22981  * For deepcopy() "copyID" is zero for a full copy or the ID for when a
22982  * reference to an already copied list/dict can be used.
22983  * Returns FAIL or OK.
22984  */
22985     static int
22986 item_copy(
22987     typval_T	*from,
22988     typval_T	*to,
22989     int		deep,
22990     int		copyID)
22991 {
22992     static int	recurse = 0;
22993     int		ret = OK;
22994 
22995     if (recurse >= DICT_MAXNEST)
22996     {
22997 	EMSG(_("E698: variable nested too deep for making a copy"));
22998 	return FAIL;
22999     }
23000     ++recurse;
23001 
23002     switch (from->v_type)
23003     {
23004 	case VAR_NUMBER:
23005 	case VAR_FLOAT:
23006 	case VAR_STRING:
23007 	case VAR_FUNC:
23008 	case VAR_PARTIAL:
23009 	case VAR_SPECIAL:
23010 	case VAR_JOB:
23011 	case VAR_CHANNEL:
23012 	    copy_tv(from, to);
23013 	    break;
23014 	case VAR_LIST:
23015 	    to->v_type = VAR_LIST;
23016 	    to->v_lock = 0;
23017 	    if (from->vval.v_list == NULL)
23018 		to->vval.v_list = NULL;
23019 	    else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID)
23020 	    {
23021 		/* use the copy made earlier */
23022 		to->vval.v_list = from->vval.v_list->lv_copylist;
23023 		++to->vval.v_list->lv_refcount;
23024 	    }
23025 	    else
23026 		to->vval.v_list = list_copy(from->vval.v_list, deep, copyID);
23027 	    if (to->vval.v_list == NULL)
23028 		ret = FAIL;
23029 	    break;
23030 	case VAR_DICT:
23031 	    to->v_type = VAR_DICT;
23032 	    to->v_lock = 0;
23033 	    if (from->vval.v_dict == NULL)
23034 		to->vval.v_dict = NULL;
23035 	    else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID)
23036 	    {
23037 		/* use the copy made earlier */
23038 		to->vval.v_dict = from->vval.v_dict->dv_copydict;
23039 		++to->vval.v_dict->dv_refcount;
23040 	    }
23041 	    else
23042 		to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID);
23043 	    if (to->vval.v_dict == NULL)
23044 		ret = FAIL;
23045 	    break;
23046 	case VAR_UNKNOWN:
23047 	    EMSG2(_(e_intern2), "item_copy(UNKNOWN)");
23048 	    ret = FAIL;
23049     }
23050     --recurse;
23051     return ret;
23052 }
23053 
23054 /*
23055  * ":echo expr1 ..."	print each argument separated with a space, add a
23056  *			newline at the end.
23057  * ":echon expr1 ..."	print each argument plain.
23058  */
23059     void
23060 ex_echo(exarg_T *eap)
23061 {
23062     char_u	*arg = eap->arg;
23063     typval_T	rettv;
23064     char_u	*tofree;
23065     char_u	*p;
23066     int		needclr = TRUE;
23067     int		atstart = TRUE;
23068     char_u	numbuf[NUMBUFLEN];
23069 
23070     if (eap->skip)
23071 	++emsg_skip;
23072     while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
23073     {
23074 	/* If eval1() causes an error message the text from the command may
23075 	 * still need to be cleared. E.g., "echo 22,44". */
23076 	need_clr_eos = needclr;
23077 
23078 	p = arg;
23079 	if (eval1(&arg, &rettv, !eap->skip) == FAIL)
23080 	{
23081 	    /*
23082 	     * Report the invalid expression unless the expression evaluation
23083 	     * has been cancelled due to an aborting error, an interrupt, or an
23084 	     * exception.
23085 	     */
23086 	    if (!aborting())
23087 		EMSG2(_(e_invexpr2), p);
23088 	    need_clr_eos = FALSE;
23089 	    break;
23090 	}
23091 	need_clr_eos = FALSE;
23092 
23093 	if (!eap->skip)
23094 	{
23095 	    if (atstart)
23096 	    {
23097 		atstart = FALSE;
23098 		/* Call msg_start() after eval1(), evaluating the expression
23099 		 * may cause a message to appear. */
23100 		if (eap->cmdidx == CMD_echo)
23101 		{
23102 		    /* Mark the saved text as finishing the line, so that what
23103 		     * follows is displayed on a new line when scrolling back
23104 		     * at the more prompt. */
23105 		    msg_sb_eol();
23106 		    msg_start();
23107 		}
23108 	    }
23109 	    else if (eap->cmdidx == CMD_echo)
23110 		msg_puts_attr((char_u *)" ", echo_attr);
23111 	    p = echo_string(&rettv, &tofree, numbuf, get_copyID());
23112 	    if (p != NULL)
23113 		for ( ; *p != NUL && !got_int; ++p)
23114 		{
23115 		    if (*p == '\n' || *p == '\r' || *p == TAB)
23116 		    {
23117 			if (*p != TAB && needclr)
23118 			{
23119 			    /* remove any text still there from the command */
23120 			    msg_clr_eos();
23121 			    needclr = FALSE;
23122 			}
23123 			msg_putchar_attr(*p, echo_attr);
23124 		    }
23125 		    else
23126 		    {
23127 #ifdef FEAT_MBYTE
23128 			if (has_mbyte)
23129 			{
23130 			    int i = (*mb_ptr2len)(p);
23131 
23132 			    (void)msg_outtrans_len_attr(p, i, echo_attr);
23133 			    p += i - 1;
23134 			}
23135 			else
23136 #endif
23137 			    (void)msg_outtrans_len_attr(p, 1, echo_attr);
23138 		    }
23139 		}
23140 	    vim_free(tofree);
23141 	}
23142 	clear_tv(&rettv);
23143 	arg = skipwhite(arg);
23144     }
23145     eap->nextcmd = check_nextcmd(arg);
23146 
23147     if (eap->skip)
23148 	--emsg_skip;
23149     else
23150     {
23151 	/* remove text that may still be there from the command */
23152 	if (needclr)
23153 	    msg_clr_eos();
23154 	if (eap->cmdidx == CMD_echo)
23155 	    msg_end();
23156     }
23157 }
23158 
23159 /*
23160  * ":echohl {name}".
23161  */
23162     void
23163 ex_echohl(exarg_T *eap)
23164 {
23165     int		id;
23166 
23167     id = syn_name2id(eap->arg);
23168     if (id == 0)
23169 	echo_attr = 0;
23170     else
23171 	echo_attr = syn_id2attr(id);
23172 }
23173 
23174 /*
23175  * ":execute expr1 ..."	execute the result of an expression.
23176  * ":echomsg expr1 ..."	Print a message
23177  * ":echoerr expr1 ..."	Print an error
23178  * Each gets spaces around each argument and a newline at the end for
23179  * echo commands
23180  */
23181     void
23182 ex_execute(exarg_T *eap)
23183 {
23184     char_u	*arg = eap->arg;
23185     typval_T	rettv;
23186     int		ret = OK;
23187     char_u	*p;
23188     garray_T	ga;
23189     int		len;
23190     int		save_did_emsg;
23191 
23192     ga_init2(&ga, 1, 80);
23193 
23194     if (eap->skip)
23195 	++emsg_skip;
23196     while (*arg != NUL && *arg != '|' && *arg != '\n')
23197     {
23198 	p = arg;
23199 	if (eval1(&arg, &rettv, !eap->skip) == FAIL)
23200 	{
23201 	    /*
23202 	     * Report the invalid expression unless the expression evaluation
23203 	     * has been cancelled due to an aborting error, an interrupt, or an
23204 	     * exception.
23205 	     */
23206 	    if (!aborting())
23207 		EMSG2(_(e_invexpr2), p);
23208 	    ret = FAIL;
23209 	    break;
23210 	}
23211 
23212 	if (!eap->skip)
23213 	{
23214 	    p = get_tv_string(&rettv);
23215 	    len = (int)STRLEN(p);
23216 	    if (ga_grow(&ga, len + 2) == FAIL)
23217 	    {
23218 		clear_tv(&rettv);
23219 		ret = FAIL;
23220 		break;
23221 	    }
23222 	    if (ga.ga_len)
23223 		((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
23224 	    STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
23225 	    ga.ga_len += len;
23226 	}
23227 
23228 	clear_tv(&rettv);
23229 	arg = skipwhite(arg);
23230     }
23231 
23232     if (ret != FAIL && ga.ga_data != NULL)
23233     {
23234 	if (eap->cmdidx == CMD_echomsg)
23235 	{
23236 	    MSG_ATTR(ga.ga_data, echo_attr);
23237 	    out_flush();
23238 	}
23239 	else if (eap->cmdidx == CMD_echoerr)
23240 	{
23241 	    /* We don't want to abort following commands, restore did_emsg. */
23242 	    save_did_emsg = did_emsg;
23243 	    EMSG((char_u *)ga.ga_data);
23244 	    if (!force_abort)
23245 		did_emsg = save_did_emsg;
23246 	}
23247 	else if (eap->cmdidx == CMD_execute)
23248 	    do_cmdline((char_u *)ga.ga_data,
23249 		       eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
23250     }
23251 
23252     ga_clear(&ga);
23253 
23254     if (eap->skip)
23255 	--emsg_skip;
23256 
23257     eap->nextcmd = check_nextcmd(arg);
23258 }
23259 
23260 /*
23261  * Skip over the name of an option: "&option", "&g:option" or "&l:option".
23262  * "arg" points to the "&" or '+' when called, to "option" when returning.
23263  * Returns NULL when no option name found.  Otherwise pointer to the char
23264  * after the option name.
23265  */
23266     static char_u *
23267 find_option_end(char_u **arg, int *opt_flags)
23268 {
23269     char_u	*p = *arg;
23270 
23271     ++p;
23272     if (*p == 'g' && p[1] == ':')
23273     {
23274 	*opt_flags = OPT_GLOBAL;
23275 	p += 2;
23276     }
23277     else if (*p == 'l' && p[1] == ':')
23278     {
23279 	*opt_flags = OPT_LOCAL;
23280 	p += 2;
23281     }
23282     else
23283 	*opt_flags = 0;
23284 
23285     if (!ASCII_ISALPHA(*p))
23286 	return NULL;
23287     *arg = p;
23288 
23289     if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
23290 	p += 4;	    /* termcap option */
23291     else
23292 	while (ASCII_ISALPHA(*p))
23293 	    ++p;
23294     return p;
23295 }
23296 
23297 /*
23298  * ":function"
23299  */
23300     void
23301 ex_function(exarg_T *eap)
23302 {
23303     char_u	*theline;
23304     int		i;
23305     int		j;
23306     int		c;
23307     int		saved_did_emsg;
23308     int		saved_wait_return = need_wait_return;
23309     char_u	*name = NULL;
23310     char_u	*p;
23311     char_u	*arg;
23312     char_u	*line_arg = NULL;
23313     garray_T	newargs;
23314     garray_T	newlines;
23315     int		varargs = FALSE;
23316     int		mustend = FALSE;
23317     int		flags = 0;
23318     ufunc_T	*fp;
23319     int		indent;
23320     int		nesting;
23321     char_u	*skip_until = NULL;
23322     dictitem_T	*v;
23323     funcdict_T	fudi;
23324     static int	func_nr = 0;	    /* number for nameless function */
23325     int		paren;
23326     hashtab_T	*ht;
23327     int		todo;
23328     hashitem_T	*hi;
23329     int		sourcing_lnum_off;
23330 
23331     /*
23332      * ":function" without argument: list functions.
23333      */
23334     if (ends_excmd(*eap->arg))
23335     {
23336 	if (!eap->skip)
23337 	{
23338 	    todo = (int)func_hashtab.ht_used;
23339 	    for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
23340 	    {
23341 		if (!HASHITEM_EMPTY(hi))
23342 		{
23343 		    --todo;
23344 		    fp = HI2UF(hi);
23345 		    if (!isdigit(*fp->uf_name))
23346 			list_func_head(fp, FALSE);
23347 		}
23348 	    }
23349 	}
23350 	eap->nextcmd = check_nextcmd(eap->arg);
23351 	return;
23352     }
23353 
23354     /*
23355      * ":function /pat": list functions matching pattern.
23356      */
23357     if (*eap->arg == '/')
23358     {
23359 	p = skip_regexp(eap->arg + 1, '/', TRUE, NULL);
23360 	if (!eap->skip)
23361 	{
23362 	    regmatch_T	regmatch;
23363 
23364 	    c = *p;
23365 	    *p = NUL;
23366 	    regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC);
23367 	    *p = c;
23368 	    if (regmatch.regprog != NULL)
23369 	    {
23370 		regmatch.rm_ic = p_ic;
23371 
23372 		todo = (int)func_hashtab.ht_used;
23373 		for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi)
23374 		{
23375 		    if (!HASHITEM_EMPTY(hi))
23376 		    {
23377 			--todo;
23378 			fp = HI2UF(hi);
23379 			if (!isdigit(*fp->uf_name)
23380 				    && vim_regexec(&regmatch, fp->uf_name, 0))
23381 			    list_func_head(fp, FALSE);
23382 		    }
23383 		}
23384 		vim_regfree(regmatch.regprog);
23385 	    }
23386 	}
23387 	if (*p == '/')
23388 	    ++p;
23389 	eap->nextcmd = check_nextcmd(p);
23390 	return;
23391     }
23392 
23393     /*
23394      * Get the function name.  There are these situations:
23395      * func	    normal function name
23396      *		    "name" == func, "fudi.fd_dict" == NULL
23397      * dict.func    new dictionary entry
23398      *		    "name" == NULL, "fudi.fd_dict" set,
23399      *		    "fudi.fd_di" == NULL, "fudi.fd_newkey" == func
23400      * dict.func    existing dict entry with a Funcref
23401      *		    "name" == func, "fudi.fd_dict" set,
23402      *		    "fudi.fd_di" set, "fudi.fd_newkey" == NULL
23403      * dict.func    existing dict entry that's not a Funcref
23404      *		    "name" == NULL, "fudi.fd_dict" set,
23405      *		    "fudi.fd_di" set, "fudi.fd_newkey" == NULL
23406      * s:func	    script-local function name
23407      * g:func	    global function name, same as "func"
23408      */
23409     p = eap->arg;
23410     name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
23411     paren = (vim_strchr(p, '(') != NULL);
23412     if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
23413     {
23414 	/*
23415 	 * Return on an invalid expression in braces, unless the expression
23416 	 * evaluation has been cancelled due to an aborting error, an
23417 	 * interrupt, or an exception.
23418 	 */
23419 	if (!aborting())
23420 	{
23421 	    if (!eap->skip && fudi.fd_newkey != NULL)
23422 		EMSG2(_(e_dictkey), fudi.fd_newkey);
23423 	    vim_free(fudi.fd_newkey);
23424 	    return;
23425 	}
23426 	else
23427 	    eap->skip = TRUE;
23428     }
23429 
23430     /* An error in a function call during evaluation of an expression in magic
23431      * braces should not cause the function not to be defined. */
23432     saved_did_emsg = did_emsg;
23433     did_emsg = FALSE;
23434 
23435     /*
23436      * ":function func" with only function name: list function.
23437      */
23438     if (!paren)
23439     {
23440 	if (!ends_excmd(*skipwhite(p)))
23441 	{
23442 	    EMSG(_(e_trailing));
23443 	    goto ret_free;
23444 	}
23445 	eap->nextcmd = check_nextcmd(p);
23446 	if (eap->nextcmd != NULL)
23447 	    *p = NUL;
23448 	if (!eap->skip && !got_int)
23449 	{
23450 	    fp = find_func(name);
23451 	    if (fp != NULL)
23452 	    {
23453 		list_func_head(fp, TRUE);
23454 		for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j)
23455 		{
23456 		    if (FUNCLINE(fp, j) == NULL)
23457 			continue;
23458 		    msg_putchar('\n');
23459 		    msg_outnum((long)(j + 1));
23460 		    if (j < 9)
23461 			msg_putchar(' ');
23462 		    if (j < 99)
23463 			msg_putchar(' ');
23464 		    msg_prt_line(FUNCLINE(fp, j), FALSE);
23465 		    out_flush();	/* show a line at a time */
23466 		    ui_breakcheck();
23467 		}
23468 		if (!got_int)
23469 		{
23470 		    msg_putchar('\n');
23471 		    msg_puts((char_u *)"   endfunction");
23472 		}
23473 	    }
23474 	    else
23475 		emsg_funcname(N_("E123: Undefined function: %s"), name);
23476 	}
23477 	goto ret_free;
23478     }
23479 
23480     /*
23481      * ":function name(arg1, arg2)" Define function.
23482      */
23483     p = skipwhite(p);
23484     if (*p != '(')
23485     {
23486 	if (!eap->skip)
23487 	{
23488 	    EMSG2(_("E124: Missing '(': %s"), eap->arg);
23489 	    goto ret_free;
23490 	}
23491 	/* attempt to continue by skipping some text */
23492 	if (vim_strchr(p, '(') != NULL)
23493 	    p = vim_strchr(p, '(');
23494     }
23495     p = skipwhite(p + 1);
23496 
23497     ga_init2(&newargs, (int)sizeof(char_u *), 3);
23498     ga_init2(&newlines, (int)sizeof(char_u *), 3);
23499 
23500     if (!eap->skip)
23501     {
23502 	/* Check the name of the function.  Unless it's a dictionary function
23503 	 * (that we are overwriting). */
23504 	if (name != NULL)
23505 	    arg = name;
23506 	else
23507 	    arg = fudi.fd_newkey;
23508 	if (arg != NULL && (fudi.fd_di == NULL
23509 				     || (fudi.fd_di->di_tv.v_type != VAR_FUNC
23510 				 && fudi.fd_di->di_tv.v_type != VAR_PARTIAL)))
23511 	{
23512 	    if (*arg == K_SPECIAL)
23513 		j = 3;
23514 	    else
23515 		j = 0;
23516 	    while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
23517 						      : eval_isnamec(arg[j])))
23518 		++j;
23519 	    if (arg[j] != NUL)
23520 		emsg_funcname((char *)e_invarg2, arg);
23521 	}
23522 	/* Disallow using the g: dict. */
23523 	if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE)
23524 	    EMSG(_("E862: Cannot use g: here"));
23525     }
23526 
23527     /*
23528      * Isolate the arguments: "arg1, arg2, ...)"
23529      */
23530     while (*p != ')')
23531     {
23532 	if (p[0] == '.' && p[1] == '.' && p[2] == '.')
23533 	{
23534 	    varargs = TRUE;
23535 	    p += 3;
23536 	    mustend = TRUE;
23537 	}
23538 	else
23539 	{
23540 	    arg = p;
23541 	    while (ASCII_ISALNUM(*p) || *p == '_')
23542 		++p;
23543 	    if (arg == p || isdigit(*arg)
23544 		    || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
23545 		    || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0))
23546 	    {
23547 		if (!eap->skip)
23548 		    EMSG2(_("E125: Illegal argument: %s"), arg);
23549 		break;
23550 	    }
23551 	    if (ga_grow(&newargs, 1) == FAIL)
23552 		goto erret;
23553 	    c = *p;
23554 	    *p = NUL;
23555 	    arg = vim_strsave(arg);
23556 	    if (arg == NULL)
23557 		goto erret;
23558 
23559 	    /* Check for duplicate argument name. */
23560 	    for (i = 0; i < newargs.ga_len; ++i)
23561 		if (STRCMP(((char_u **)(newargs.ga_data))[i], arg) == 0)
23562 		{
23563 		    EMSG2(_("E853: Duplicate argument name: %s"), arg);
23564 		    vim_free(arg);
23565 		    goto erret;
23566 		}
23567 
23568 	    ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
23569 	    *p = c;
23570 	    newargs.ga_len++;
23571 	    if (*p == ',')
23572 		++p;
23573 	    else
23574 		mustend = TRUE;
23575 	}
23576 	p = skipwhite(p);
23577 	if (mustend && *p != ')')
23578 	{
23579 	    if (!eap->skip)
23580 		EMSG2(_(e_invarg2), eap->arg);
23581 	    break;
23582 	}
23583     }
23584     if (*p != ')')
23585 	goto erret;
23586     ++p;	/* skip the ')' */
23587 
23588     /* find extra arguments "range", "dict" and "abort" */
23589     for (;;)
23590     {
23591 	p = skipwhite(p);
23592 	if (STRNCMP(p, "range", 5) == 0)
23593 	{
23594 	    flags |= FC_RANGE;
23595 	    p += 5;
23596 	}
23597 	else if (STRNCMP(p, "dict", 4) == 0)
23598 	{
23599 	    flags |= FC_DICT;
23600 	    p += 4;
23601 	}
23602 	else if (STRNCMP(p, "abort", 5) == 0)
23603 	{
23604 	    flags |= FC_ABORT;
23605 	    p += 5;
23606 	}
23607 	else
23608 	    break;
23609     }
23610 
23611     /* When there is a line break use what follows for the function body.
23612      * Makes 'exe "func Test()\n...\nendfunc"' work. */
23613     if (*p == '\n')
23614 	line_arg = p + 1;
23615     else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg)
23616 	EMSG(_(e_trailing));
23617 
23618     /*
23619      * Read the body of the function, until ":endfunction" is found.
23620      */
23621     if (KeyTyped)
23622     {
23623 	/* Check if the function already exists, don't let the user type the
23624 	 * whole function before telling him it doesn't work!  For a script we
23625 	 * need to skip the body to be able to find what follows. */
23626 	if (!eap->skip && !eap->forceit)
23627 	{
23628 	    if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL)
23629 		EMSG(_(e_funcdict));
23630 	    else if (name != NULL && find_func(name) != NULL)
23631 		emsg_funcname(e_funcexts, name);
23632 	}
23633 
23634 	if (!eap->skip && did_emsg)
23635 	    goto erret;
23636 
23637 	msg_putchar('\n');	    /* don't overwrite the function name */
23638 	cmdline_row = msg_row;
23639     }
23640 
23641     indent = 2;
23642     nesting = 0;
23643     for (;;)
23644     {
23645 	if (KeyTyped)
23646 	{
23647 	    msg_scroll = TRUE;
23648 	    saved_wait_return = FALSE;
23649 	}
23650 	need_wait_return = FALSE;
23651 	sourcing_lnum_off = sourcing_lnum;
23652 
23653 	if (line_arg != NULL)
23654 	{
23655 	    /* Use eap->arg, split up in parts by line breaks. */
23656 	    theline = line_arg;
23657 	    p = vim_strchr(theline, '\n');
23658 	    if (p == NULL)
23659 		line_arg += STRLEN(line_arg);
23660 	    else
23661 	    {
23662 		*p = NUL;
23663 		line_arg = p + 1;
23664 	    }
23665 	}
23666 	else if (eap->getline == NULL)
23667 	    theline = getcmdline(':', 0L, indent);
23668 	else
23669 	    theline = eap->getline(':', eap->cookie, indent);
23670 	if (KeyTyped)
23671 	    lines_left = Rows - 1;
23672 	if (theline == NULL)
23673 	{
23674 	    EMSG(_("E126: Missing :endfunction"));
23675 	    goto erret;
23676 	}
23677 
23678 	/* Detect line continuation: sourcing_lnum increased more than one. */
23679 	if (sourcing_lnum > sourcing_lnum_off + 1)
23680 	    sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1;
23681 	else
23682 	    sourcing_lnum_off = 0;
23683 
23684 	if (skip_until != NULL)
23685 	{
23686 	    /* between ":append" and "." and between ":python <<EOF" and "EOF"
23687 	     * don't check for ":endfunc". */
23688 	    if (STRCMP(theline, skip_until) == 0)
23689 	    {
23690 		vim_free(skip_until);
23691 		skip_until = NULL;
23692 	    }
23693 	}
23694 	else
23695 	{
23696 	    /* skip ':' and blanks*/
23697 	    for (p = theline; vim_iswhite(*p) || *p == ':'; ++p)
23698 		;
23699 
23700 	    /* Check for "endfunction". */
23701 	    if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0)
23702 	    {
23703 		if (line_arg == NULL)
23704 		    vim_free(theline);
23705 		break;
23706 	    }
23707 
23708 	    /* Increase indent inside "if", "while", "for" and "try", decrease
23709 	     * at "end". */
23710 	    if (indent > 2 && STRNCMP(p, "end", 3) == 0)
23711 		indent -= 2;
23712 	    else if (STRNCMP(p, "if", 2) == 0
23713 		    || STRNCMP(p, "wh", 2) == 0
23714 		    || STRNCMP(p, "for", 3) == 0
23715 		    || STRNCMP(p, "try", 3) == 0)
23716 		indent += 2;
23717 
23718 	    /* Check for defining a function inside this function. */
23719 	    if (checkforcmd(&p, "function", 2))
23720 	    {
23721 		if (*p == '!')
23722 		    p = skipwhite(p + 1);
23723 		p += eval_fname_script(p);
23724 		vim_free(trans_function_name(&p, TRUE, 0, NULL, NULL));
23725 		if (*skipwhite(p) == '(')
23726 		{
23727 		    ++nesting;
23728 		    indent += 2;
23729 		}
23730 	    }
23731 
23732 	    /* Check for ":append" or ":insert". */
23733 	    p = skip_range(p, NULL);
23734 	    if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
23735 		    || (p[0] == 'i'
23736 			&& (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
23737 				&& (!ASCII_ISALPHA(p[2]) || (p[2] == 's'))))))
23738 		skip_until = vim_strsave((char_u *)".");
23739 
23740 	    /* Check for ":python <<EOF", ":tcl <<EOF", etc. */
23741 	    arg = skipwhite(skiptowhite(p));
23742 	    if (arg[0] == '<' && arg[1] =='<'
23743 		    && ((p[0] == 'p' && p[1] == 'y'
23744 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 't'))
23745 			|| (p[0] == 'p' && p[1] == 'e'
23746 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
23747 			|| (p[0] == 't' && p[1] == 'c'
23748 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'l'))
23749 			|| (p[0] == 'l' && p[1] == 'u' && p[2] == 'a'
23750 				    && !ASCII_ISALPHA(p[3]))
23751 			|| (p[0] == 'r' && p[1] == 'u' && p[2] == 'b'
23752 				    && (!ASCII_ISALPHA(p[3]) || p[3] == 'y'))
23753 			|| (p[0] == 'm' && p[1] == 'z'
23754 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 's'))
23755 			))
23756 	    {
23757 		/* ":python <<" continues until a dot, like ":append" */
23758 		p = skipwhite(arg + 2);
23759 		if (*p == NUL)
23760 		    skip_until = vim_strsave((char_u *)".");
23761 		else
23762 		    skip_until = vim_strsave(p);
23763 	    }
23764 	}
23765 
23766 	/* Add the line to the function. */
23767 	if (ga_grow(&newlines, 1 + sourcing_lnum_off) == FAIL)
23768 	{
23769 	    if (line_arg == NULL)
23770 		vim_free(theline);
23771 	    goto erret;
23772 	}
23773 
23774 	/* Copy the line to newly allocated memory.  get_one_sourceline()
23775 	 * allocates 250 bytes per line, this saves 80% on average.  The cost
23776 	 * is an extra alloc/free. */
23777 	p = vim_strsave(theline);
23778 	if (p != NULL)
23779 	{
23780 	    if (line_arg == NULL)
23781 		vim_free(theline);
23782 	    theline = p;
23783 	}
23784 
23785 	((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline;
23786 
23787 	/* Add NULL lines for continuation lines, so that the line count is
23788 	 * equal to the index in the growarray.   */
23789 	while (sourcing_lnum_off-- > 0)
23790 	    ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL;
23791 
23792 	/* Check for end of eap->arg. */
23793 	if (line_arg != NULL && *line_arg == NUL)
23794 	    line_arg = NULL;
23795     }
23796 
23797     /* Don't define the function when skipping commands or when an error was
23798      * detected. */
23799     if (eap->skip || did_emsg)
23800 	goto erret;
23801 
23802     /*
23803      * If there are no errors, add the function
23804      */
23805     if (fudi.fd_dict == NULL)
23806     {
23807 	v = find_var(name, &ht, FALSE);
23808 	if (v != NULL && v->di_tv.v_type == VAR_FUNC)
23809 	{
23810 	    emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
23811 									name);
23812 	    goto erret;
23813 	}
23814 
23815 	fp = find_func(name);
23816 	if (fp != NULL)
23817 	{
23818 	    if (!eap->forceit)
23819 	    {
23820 		emsg_funcname(e_funcexts, name);
23821 		goto erret;
23822 	    }
23823 	    if (fp->uf_calls > 0)
23824 	    {
23825 		emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
23826 									name);
23827 		goto erret;
23828 	    }
23829 	    /* redefine existing function */
23830 	    ga_clear_strings(&(fp->uf_args));
23831 	    ga_clear_strings(&(fp->uf_lines));
23832 	    vim_free(name);
23833 	    name = NULL;
23834 	}
23835     }
23836     else
23837     {
23838 	char	numbuf[20];
23839 
23840 	fp = NULL;
23841 	if (fudi.fd_newkey == NULL && !eap->forceit)
23842 	{
23843 	    EMSG(_(e_funcdict));
23844 	    goto erret;
23845 	}
23846 	if (fudi.fd_di == NULL)
23847 	{
23848 	    /* Can't add a function to a locked dictionary */
23849 	    if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg, FALSE))
23850 		goto erret;
23851 	}
23852 	    /* Can't change an existing function if it is locked */
23853 	else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, FALSE))
23854 	    goto erret;
23855 
23856 	/* Give the function a sequential number.  Can only be used with a
23857 	 * Funcref! */
23858 	vim_free(name);
23859 	sprintf(numbuf, "%d", ++func_nr);
23860 	name = vim_strsave((char_u *)numbuf);
23861 	if (name == NULL)
23862 	    goto erret;
23863     }
23864 
23865     if (fp == NULL)
23866     {
23867 	if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL)
23868 	{
23869 	    int	    slen, plen;
23870 	    char_u  *scriptname;
23871 
23872 	    /* Check that the autoload name matches the script name. */
23873 	    j = FAIL;
23874 	    if (sourcing_name != NULL)
23875 	    {
23876 		scriptname = autoload_name(name);
23877 		if (scriptname != NULL)
23878 		{
23879 		    p = vim_strchr(scriptname, '/');
23880 		    plen = (int)STRLEN(p);
23881 		    slen = (int)STRLEN(sourcing_name);
23882 		    if (slen > plen && fnamecmp(p,
23883 					    sourcing_name + slen - plen) == 0)
23884 			j = OK;
23885 		    vim_free(scriptname);
23886 		}
23887 	    }
23888 	    if (j == FAIL)
23889 	    {
23890 		EMSG2(_("E746: Function name does not match script file name: %s"), name);
23891 		goto erret;
23892 	    }
23893 	}
23894 
23895 	fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name)));
23896 	if (fp == NULL)
23897 	    goto erret;
23898 
23899 	if (fudi.fd_dict != NULL)
23900 	{
23901 	    if (fudi.fd_di == NULL)
23902 	    {
23903 		/* add new dict entry */
23904 		fudi.fd_di = dictitem_alloc(fudi.fd_newkey);
23905 		if (fudi.fd_di == NULL)
23906 		{
23907 		    vim_free(fp);
23908 		    goto erret;
23909 		}
23910 		if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL)
23911 		{
23912 		    vim_free(fudi.fd_di);
23913 		    vim_free(fp);
23914 		    goto erret;
23915 		}
23916 	    }
23917 	    else
23918 		/* overwrite existing dict entry */
23919 		clear_tv(&fudi.fd_di->di_tv);
23920 	    fudi.fd_di->di_tv.v_type = VAR_FUNC;
23921 	    fudi.fd_di->di_tv.v_lock = 0;
23922 	    fudi.fd_di->di_tv.vval.v_string = vim_strsave(name);
23923 	    fp->uf_refcount = 1;
23924 
23925 	    /* behave like "dict" was used */
23926 	    flags |= FC_DICT;
23927 	}
23928 
23929 	/* insert the new function in the function list */
23930 	STRCPY(fp->uf_name, name);
23931 	if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL)
23932 	{
23933 	    vim_free(fp);
23934 	    goto erret;
23935 	}
23936     }
23937     fp->uf_args = newargs;
23938     fp->uf_lines = newlines;
23939 #ifdef FEAT_PROFILE
23940     fp->uf_tml_count = NULL;
23941     fp->uf_tml_total = NULL;
23942     fp->uf_tml_self = NULL;
23943     fp->uf_profiling = FALSE;
23944     if (prof_def_func())
23945 	func_do_profile(fp);
23946 #endif
23947     fp->uf_varargs = varargs;
23948     fp->uf_flags = flags;
23949     fp->uf_calls = 0;
23950     fp->uf_script_ID = current_SID;
23951     goto ret_free;
23952 
23953 erret:
23954     ga_clear_strings(&newargs);
23955     ga_clear_strings(&newlines);
23956 ret_free:
23957     vim_free(skip_until);
23958     vim_free(fudi.fd_newkey);
23959     vim_free(name);
23960     did_emsg |= saved_did_emsg;
23961     need_wait_return |= saved_wait_return;
23962 }
23963 
23964 /*
23965  * Get a function name, translating "<SID>" and "<SNR>".
23966  * Also handles a Funcref in a List or Dictionary.
23967  * Returns the function name in allocated memory, or NULL for failure.
23968  * flags:
23969  * TFN_INT:	    internal function name OK
23970  * TFN_QUIET:	    be quiet
23971  * TFN_NO_AUTOLOAD: do not use script autoloading
23972  * Advances "pp" to just after the function name (if no error).
23973  */
23974     static char_u *
23975 trans_function_name(
23976     char_u	**pp,
23977     int		skip,		/* only find the end, don't evaluate */
23978     int		flags,
23979     funcdict_T	*fdp,		/* return: info about dictionary used */
23980     partial_T	**partial)	/* return: partial of a FuncRef */
23981 {
23982     char_u	*name = NULL;
23983     char_u	*start;
23984     char_u	*end;
23985     int		lead;
23986     char_u	sid_buf[20];
23987     int		len;
23988     lval_T	lv;
23989 
23990     if (fdp != NULL)
23991 	vim_memset(fdp, 0, sizeof(funcdict_T));
23992     start = *pp;
23993 
23994     /* Check for hard coded <SNR>: already translated function ID (from a user
23995      * command). */
23996     if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA
23997 						   && (*pp)[2] == (int)KE_SNR)
23998     {
23999 	*pp += 3;
24000 	len = get_id_len(pp) + 3;
24001 	return vim_strnsave(start, len);
24002     }
24003 
24004     /* A name starting with "<SID>" or "<SNR>" is local to a script.  But
24005      * don't skip over "s:", get_lval() needs it for "s:dict.func". */
24006     lead = eval_fname_script(start);
24007     if (lead > 2)
24008 	start += lead;
24009 
24010     /* Note that TFN_ flags use the same values as GLV_ flags. */
24011     end = get_lval(start, NULL, &lv, FALSE, skip, flags,
24012 					      lead > 2 ? 0 : FNE_CHECK_START);
24013     if (end == start)
24014     {
24015 	if (!skip)
24016 	    EMSG(_("E129: Function name required"));
24017 	goto theend;
24018     }
24019     if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range)))
24020     {
24021 	/*
24022 	 * Report an invalid expression in braces, unless the expression
24023 	 * evaluation has been cancelled due to an aborting error, an
24024 	 * interrupt, or an exception.
24025 	 */
24026 	if (!aborting())
24027 	{
24028 	    if (end != NULL)
24029 		EMSG2(_(e_invarg2), start);
24030 	}
24031 	else
24032 	    *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR);
24033 	goto theend;
24034     }
24035 
24036     if (lv.ll_tv != NULL)
24037     {
24038 	if (fdp != NULL)
24039 	{
24040 	    fdp->fd_dict = lv.ll_dict;
24041 	    fdp->fd_newkey = lv.ll_newkey;
24042 	    lv.ll_newkey = NULL;
24043 	    fdp->fd_di = lv.ll_di;
24044 	}
24045 	if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL)
24046 	{
24047 	    name = vim_strsave(lv.ll_tv->vval.v_string);
24048 	    *pp = end;
24049 	}
24050 	else if (lv.ll_tv->v_type == VAR_PARTIAL
24051 					  && lv.ll_tv->vval.v_partial != NULL)
24052 	{
24053 	    name = vim_strsave(lv.ll_tv->vval.v_partial->pt_name);
24054 	    *pp = end;
24055 	    if (partial != NULL)
24056 		*partial = lv.ll_tv->vval.v_partial;
24057 	}
24058 	else
24059 	{
24060 	    if (!skip && !(flags & TFN_QUIET) && (fdp == NULL
24061 			     || lv.ll_dict == NULL || fdp->fd_newkey == NULL))
24062 		EMSG(_(e_funcref));
24063 	    else
24064 		*pp = end;
24065 	    name = NULL;
24066 	}
24067 	goto theend;
24068     }
24069 
24070     if (lv.ll_name == NULL)
24071     {
24072 	/* Error found, but continue after the function name. */
24073 	*pp = end;
24074 	goto theend;
24075     }
24076 
24077     /* Check if the name is a Funcref.  If so, use the value. */
24078     if (lv.ll_exp_name != NULL)
24079     {
24080 	len = (int)STRLEN(lv.ll_exp_name);
24081 	name = deref_func_name(lv.ll_exp_name, &len, partial,
24082 						     flags & TFN_NO_AUTOLOAD);
24083 	if (name == lv.ll_exp_name)
24084 	    name = NULL;
24085     }
24086     else
24087     {
24088 	len = (int)(end - *pp);
24089 	name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD);
24090 	if (name == *pp)
24091 	    name = NULL;
24092     }
24093     if (name != NULL)
24094     {
24095 	name = vim_strsave(name);
24096 	*pp = end;
24097 	if (STRNCMP(name, "<SNR>", 5) == 0)
24098 	{
24099 	    /* Change "<SNR>" to the byte sequence. */
24100 	    name[0] = K_SPECIAL;
24101 	    name[1] = KS_EXTRA;
24102 	    name[2] = (int)KE_SNR;
24103 	    mch_memmove(name + 3, name + 5, STRLEN(name + 5) + 1);
24104 	}
24105 	goto theend;
24106     }
24107 
24108     if (lv.ll_exp_name != NULL)
24109     {
24110 	len = (int)STRLEN(lv.ll_exp_name);
24111 	if (lead <= 2 && lv.ll_name == lv.ll_exp_name
24112 					 && STRNCMP(lv.ll_name, "s:", 2) == 0)
24113 	{
24114 	    /* When there was "s:" already or the name expanded to get a
24115 	     * leading "s:" then remove it. */
24116 	    lv.ll_name += 2;
24117 	    len -= 2;
24118 	    lead = 2;
24119 	}
24120     }
24121     else
24122     {
24123 	/* skip over "s:" and "g:" */
24124 	if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':'))
24125 	    lv.ll_name += 2;
24126 	len = (int)(end - lv.ll_name);
24127     }
24128 
24129     /*
24130      * Copy the function name to allocated memory.
24131      * Accept <SID>name() inside a script, translate into <SNR>123_name().
24132      * Accept <SNR>123_name() outside a script.
24133      */
24134     if (skip)
24135 	lead = 0;	/* do nothing */
24136     else if (lead > 0)
24137     {
24138 	lead = 3;
24139 	if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name))
24140 						       || eval_fname_sid(*pp))
24141 	{
24142 	    /* It's "s:" or "<SID>" */
24143 	    if (current_SID <= 0)
24144 	    {
24145 		EMSG(_(e_usingsid));
24146 		goto theend;
24147 	    }
24148 	    sprintf((char *)sid_buf, "%ld_", (long)current_SID);
24149 	    lead += (int)STRLEN(sid_buf);
24150 	}
24151     }
24152     else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len))
24153     {
24154 	EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"),
24155 								       start);
24156 	goto theend;
24157     }
24158     if (!skip && !(flags & TFN_QUIET))
24159     {
24160 	char_u *cp = vim_strchr(lv.ll_name, ':');
24161 
24162 	if (cp != NULL && cp < end)
24163 	{
24164 	    EMSG2(_("E884: Function name cannot contain a colon: %s"), start);
24165 	    goto theend;
24166 	}
24167     }
24168 
24169     name = alloc((unsigned)(len + lead + 1));
24170     if (name != NULL)
24171     {
24172 	if (lead > 0)
24173 	{
24174 	    name[0] = K_SPECIAL;
24175 	    name[1] = KS_EXTRA;
24176 	    name[2] = (int)KE_SNR;
24177 	    if (lead > 3)	/* If it's "<SID>" */
24178 		STRCPY(name + 3, sid_buf);
24179 	}
24180 	mch_memmove(name + lead, lv.ll_name, (size_t)len);
24181 	name[lead + len] = NUL;
24182     }
24183     *pp = end;
24184 
24185 theend:
24186     clear_lval(&lv);
24187     return name;
24188 }
24189 
24190 /*
24191  * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
24192  * Return 2 if "p" starts with "s:".
24193  * Return 0 otherwise.
24194  */
24195     static int
24196 eval_fname_script(char_u *p)
24197 {
24198     /* Use MB_STRICMP() because in Turkish comparing the "I" may not work with
24199      * the standard library function. */
24200     if (p[0] == '<' && (MB_STRNICMP(p + 1, "SID>", 4) == 0
24201 				       || MB_STRNICMP(p + 1, "SNR>", 4) == 0))
24202 	return 5;
24203     if (p[0] == 's' && p[1] == ':')
24204 	return 2;
24205     return 0;
24206 }
24207 
24208 /*
24209  * Return TRUE if "p" starts with "<SID>" or "s:".
24210  * Only works if eval_fname_script() returned non-zero for "p"!
24211  */
24212     static int
24213 eval_fname_sid(char_u *p)
24214 {
24215     return (*p == 's' || TOUPPER_ASC(p[2]) == 'I');
24216 }
24217 
24218 /*
24219  * List the head of the function: "name(arg1, arg2)".
24220  */
24221     static void
24222 list_func_head(ufunc_T *fp, int indent)
24223 {
24224     int		j;
24225 
24226     msg_start();
24227     if (indent)
24228 	MSG_PUTS("   ");
24229     MSG_PUTS("function ");
24230     if (fp->uf_name[0] == K_SPECIAL)
24231     {
24232 	MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
24233 	msg_puts(fp->uf_name + 3);
24234     }
24235     else
24236 	msg_puts(fp->uf_name);
24237     msg_putchar('(');
24238     for (j = 0; j < fp->uf_args.ga_len; ++j)
24239     {
24240 	if (j)
24241 	    MSG_PUTS(", ");
24242 	msg_puts(FUNCARG(fp, j));
24243     }
24244     if (fp->uf_varargs)
24245     {
24246 	if (j)
24247 	    MSG_PUTS(", ");
24248 	MSG_PUTS("...");
24249     }
24250     msg_putchar(')');
24251     if (fp->uf_flags & FC_ABORT)
24252 	MSG_PUTS(" abort");
24253     if (fp->uf_flags & FC_RANGE)
24254 	MSG_PUTS(" range");
24255     if (fp->uf_flags & FC_DICT)
24256 	MSG_PUTS(" dict");
24257     msg_clr_eos();
24258     if (p_verbose > 0)
24259 	last_set_msg(fp->uf_script_ID);
24260 }
24261 
24262 /*
24263  * Find a function by name, return pointer to it in ufuncs.
24264  * Return NULL for unknown function.
24265  */
24266     static ufunc_T *
24267 find_func(char_u *name)
24268 {
24269     hashitem_T	*hi;
24270 
24271     hi = hash_find(&func_hashtab, name);
24272     if (!HASHITEM_EMPTY(hi))
24273 	return HI2UF(hi);
24274     return NULL;
24275 }
24276 
24277 #if defined(EXITFREE) || defined(PROTO)
24278     void
24279 free_all_functions(void)
24280 {
24281     hashitem_T	*hi;
24282 
24283     /* Need to start all over every time, because func_free() may change the
24284      * hash table. */
24285     while (func_hashtab.ht_used > 0)
24286 	for (hi = func_hashtab.ht_array; ; ++hi)
24287 	    if (!HASHITEM_EMPTY(hi))
24288 	    {
24289 		func_free(HI2UF(hi));
24290 		break;
24291 	    }
24292 }
24293 #endif
24294 
24295     int
24296 translated_function_exists(char_u *name)
24297 {
24298     if (builtin_function(name, -1))
24299 	return find_internal_func(name) >= 0;
24300     return find_func(name) != NULL;
24301 }
24302 
24303 /*
24304  * Return TRUE if a function "name" exists.
24305  */
24306     static int
24307 function_exists(char_u *name)
24308 {
24309     char_u  *nm = name;
24310     char_u  *p;
24311     int	    n = FALSE;
24312 
24313     p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
24314 			    NULL, NULL);
24315     nm = skipwhite(nm);
24316 
24317     /* Only accept "funcname", "funcname ", "funcname (..." and
24318      * "funcname(...", not "funcname!...". */
24319     if (p != NULL && (*nm == NUL || *nm == '('))
24320 	n = translated_function_exists(p);
24321     vim_free(p);
24322     return n;
24323 }
24324 
24325     char_u *
24326 get_expanded_name(char_u *name, int check)
24327 {
24328     char_u	*nm = name;
24329     char_u	*p;
24330 
24331     p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL, NULL);
24332 
24333     if (p != NULL && *nm == NUL)
24334 	if (!check || translated_function_exists(p))
24335 	    return p;
24336 
24337     vim_free(p);
24338     return NULL;
24339 }
24340 
24341 /*
24342  * Return TRUE if "name" looks like a builtin function name: starts with a
24343  * lower case letter and doesn't contain AUTOLOAD_CHAR.
24344  * "len" is the length of "name", or -1 for NUL terminated.
24345  */
24346     static int
24347 builtin_function(char_u *name, int len)
24348 {
24349     char_u *p;
24350 
24351     if (!ASCII_ISLOWER(name[0]))
24352 	return FALSE;
24353     p = vim_strchr(name, AUTOLOAD_CHAR);
24354     return p == NULL || (len > 0 && p > name + len);
24355 }
24356 
24357 #if defined(FEAT_PROFILE) || defined(PROTO)
24358 /*
24359  * Start profiling function "fp".
24360  */
24361     static void
24362 func_do_profile(ufunc_T *fp)
24363 {
24364     int		len = fp->uf_lines.ga_len;
24365 
24366     if (len == 0)
24367 	len = 1;  /* avoid getting error for allocating zero bytes */
24368     fp->uf_tm_count = 0;
24369     profile_zero(&fp->uf_tm_self);
24370     profile_zero(&fp->uf_tm_total);
24371     if (fp->uf_tml_count == NULL)
24372 	fp->uf_tml_count = (int *)alloc_clear((unsigned) (sizeof(int) * len));
24373     if (fp->uf_tml_total == NULL)
24374 	fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned)
24375 						  (sizeof(proftime_T) * len));
24376     if (fp->uf_tml_self == NULL)
24377 	fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned)
24378 						  (sizeof(proftime_T) * len));
24379     fp->uf_tml_idx = -1;
24380     if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL
24381 						   || fp->uf_tml_self == NULL)
24382 	return;	    /* out of memory */
24383 
24384     fp->uf_profiling = TRUE;
24385 }
24386 
24387 /*
24388  * Dump the profiling results for all functions in file "fd".
24389  */
24390     void
24391 func_dump_profile(FILE *fd)
24392 {
24393     hashitem_T	*hi;
24394     int		todo;
24395     ufunc_T	*fp;
24396     int		i;
24397     ufunc_T	**sorttab;
24398     int		st_len = 0;
24399 
24400     todo = (int)func_hashtab.ht_used;
24401     if (todo == 0)
24402 	return;     /* nothing to dump */
24403 
24404     sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T *) * todo));
24405 
24406     for (hi = func_hashtab.ht_array; todo > 0; ++hi)
24407     {
24408 	if (!HASHITEM_EMPTY(hi))
24409 	{
24410 	    --todo;
24411 	    fp = HI2UF(hi);
24412 	    if (fp->uf_profiling)
24413 	    {
24414 		if (sorttab != NULL)
24415 		    sorttab[st_len++] = fp;
24416 
24417 		if (fp->uf_name[0] == K_SPECIAL)
24418 		    fprintf(fd, "FUNCTION  <SNR>%s()\n", fp->uf_name + 3);
24419 		else
24420 		    fprintf(fd, "FUNCTION  %s()\n", fp->uf_name);
24421 		if (fp->uf_tm_count == 1)
24422 		    fprintf(fd, "Called 1 time\n");
24423 		else
24424 		    fprintf(fd, "Called %d times\n", fp->uf_tm_count);
24425 		fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total));
24426 		fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self));
24427 		fprintf(fd, "\n");
24428 		fprintf(fd, "count  total (s)   self (s)\n");
24429 
24430 		for (i = 0; i < fp->uf_lines.ga_len; ++i)
24431 		{
24432 		    if (FUNCLINE(fp, i) == NULL)
24433 			continue;
24434 		    prof_func_line(fd, fp->uf_tml_count[i],
24435 			     &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE);
24436 		    fprintf(fd, "%s\n", FUNCLINE(fp, i));
24437 		}
24438 		fprintf(fd, "\n");
24439 	    }
24440 	}
24441     }
24442 
24443     if (sorttab != NULL && st_len > 0)
24444     {
24445 	qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
24446 							      prof_total_cmp);
24447 	prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE);
24448 	qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *),
24449 							      prof_self_cmp);
24450 	prof_sort_list(fd, sorttab, st_len, "SELF", TRUE);
24451     }
24452 
24453     vim_free(sorttab);
24454 }
24455 
24456     static void
24457 prof_sort_list(
24458     FILE	*fd,
24459     ufunc_T	**sorttab,
24460     int		st_len,
24461     char	*title,
24462     int		prefer_self)	/* when equal print only self time */
24463 {
24464     int		i;
24465     ufunc_T	*fp;
24466 
24467     fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title);
24468     fprintf(fd, "count  total (s)   self (s)  function\n");
24469     for (i = 0; i < 20 && i < st_len; ++i)
24470     {
24471 	fp = sorttab[i];
24472 	prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self,
24473 								 prefer_self);
24474 	if (fp->uf_name[0] == K_SPECIAL)
24475 	    fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3);
24476 	else
24477 	    fprintf(fd, " %s()\n", fp->uf_name);
24478     }
24479     fprintf(fd, "\n");
24480 }
24481 
24482 /*
24483  * Print the count and times for one function or function line.
24484  */
24485     static void
24486 prof_func_line(
24487     FILE	*fd,
24488     int		count,
24489     proftime_T	*total,
24490     proftime_T	*self,
24491     int		prefer_self)	/* when equal print only self time */
24492 {
24493     if (count > 0)
24494     {
24495 	fprintf(fd, "%5d ", count);
24496 	if (prefer_self && profile_equal(total, self))
24497 	    fprintf(fd, "           ");
24498 	else
24499 	    fprintf(fd, "%s ", profile_msg(total));
24500 	if (!prefer_self && profile_equal(total, self))
24501 	    fprintf(fd, "           ");
24502 	else
24503 	    fprintf(fd, "%s ", profile_msg(self));
24504     }
24505     else
24506 	fprintf(fd, "                            ");
24507 }
24508 
24509 /*
24510  * Compare function for total time sorting.
24511  */
24512     static int
24513 #ifdef __BORLANDC__
24514 _RTLENTRYF
24515 #endif
24516 prof_total_cmp(const void *s1, const void *s2)
24517 {
24518     ufunc_T	*p1, *p2;
24519 
24520     p1 = *(ufunc_T **)s1;
24521     p2 = *(ufunc_T **)s2;
24522     return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total);
24523 }
24524 
24525 /*
24526  * Compare function for self time sorting.
24527  */
24528     static int
24529 #ifdef __BORLANDC__
24530 _RTLENTRYF
24531 #endif
24532 prof_self_cmp(const void *s1, const void *s2)
24533 {
24534     ufunc_T	*p1, *p2;
24535 
24536     p1 = *(ufunc_T **)s1;
24537     p2 = *(ufunc_T **)s2;
24538     return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self);
24539 }
24540 
24541 #endif
24542 
24543 /*
24544  * If "name" has a package name try autoloading the script for it.
24545  * Return TRUE if a package was loaded.
24546  */
24547     static int
24548 script_autoload(
24549     char_u	*name,
24550     int		reload)	    /* load script again when already loaded */
24551 {
24552     char_u	*p;
24553     char_u	*scriptname, *tofree;
24554     int		ret = FALSE;
24555     int		i;
24556 
24557     /* If there is no '#' after name[0] there is no package name. */
24558     p = vim_strchr(name, AUTOLOAD_CHAR);
24559     if (p == NULL || p == name)
24560 	return FALSE;
24561 
24562     tofree = scriptname = autoload_name(name);
24563 
24564     /* Find the name in the list of previously loaded package names.  Skip
24565      * "autoload/", it's always the same. */
24566     for (i = 0; i < ga_loaded.ga_len; ++i)
24567 	if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
24568 	    break;
24569     if (!reload && i < ga_loaded.ga_len)
24570 	ret = FALSE;	    /* was loaded already */
24571     else
24572     {
24573 	/* Remember the name if it wasn't loaded already. */
24574 	if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK)
24575 	{
24576 	    ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname;
24577 	    tofree = NULL;
24578 	}
24579 
24580 	/* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
24581 	if (source_runtime(scriptname, 0) == OK)
24582 	    ret = TRUE;
24583     }
24584 
24585     vim_free(tofree);
24586     return ret;
24587 }
24588 
24589 /*
24590  * Return the autoload script name for a function or variable name.
24591  * Returns NULL when out of memory.
24592  */
24593     static char_u *
24594 autoload_name(char_u *name)
24595 {
24596     char_u	*p;
24597     char_u	*scriptname;
24598 
24599     /* Get the script file name: replace '#' with '/', append ".vim". */
24600     scriptname = alloc((unsigned)(STRLEN(name) + 14));
24601     if (scriptname == NULL)
24602 	return FALSE;
24603     STRCPY(scriptname, "autoload/");
24604     STRCAT(scriptname, name);
24605     *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL;
24606     STRCAT(scriptname, ".vim");
24607     while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL)
24608 	*p = '/';
24609     return scriptname;
24610 }
24611 
24612 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
24613 
24614 /*
24615  * Function given to ExpandGeneric() to obtain the list of user defined
24616  * function names.
24617  */
24618     char_u *
24619 get_user_func_name(expand_T *xp, int idx)
24620 {
24621     static long_u	done;
24622     static hashitem_T	*hi;
24623     ufunc_T		*fp;
24624 
24625     if (idx == 0)
24626     {
24627 	done = 0;
24628 	hi = func_hashtab.ht_array;
24629     }
24630     if (done < func_hashtab.ht_used)
24631     {
24632 	if (done++ > 0)
24633 	    ++hi;
24634 	while (HASHITEM_EMPTY(hi))
24635 	    ++hi;
24636 	fp = HI2UF(hi);
24637 
24638 	if (fp->uf_flags & FC_DICT)
24639 	    return (char_u *)""; /* don't show dict functions */
24640 
24641 	if (STRLEN(fp->uf_name) + 4 >= IOSIZE)
24642 	    return fp->uf_name;	/* prevents overflow */
24643 
24644 	cat_func_name(IObuff, fp);
24645 	if (xp->xp_context != EXPAND_USER_FUNC)
24646 	{
24647 	    STRCAT(IObuff, "(");
24648 	    if (!fp->uf_varargs && fp->uf_args.ga_len == 0)
24649 		STRCAT(IObuff, ")");
24650 	}
24651 	return IObuff;
24652     }
24653     return NULL;
24654 }
24655 
24656 #endif /* FEAT_CMDL_COMPL */
24657 
24658 /*
24659  * Copy the function name of "fp" to buffer "buf".
24660  * "buf" must be able to hold the function name plus three bytes.
24661  * Takes care of script-local function names.
24662  */
24663     static void
24664 cat_func_name(char_u *buf, ufunc_T *fp)
24665 {
24666     if (fp->uf_name[0] == K_SPECIAL)
24667     {
24668 	STRCPY(buf, "<SNR>");
24669 	STRCAT(buf, fp->uf_name + 3);
24670     }
24671     else
24672 	STRCPY(buf, fp->uf_name);
24673 }
24674 
24675 /*
24676  * ":delfunction {name}"
24677  */
24678     void
24679 ex_delfunction(exarg_T *eap)
24680 {
24681     ufunc_T	*fp = NULL;
24682     char_u	*p;
24683     char_u	*name;
24684     funcdict_T	fudi;
24685 
24686     p = eap->arg;
24687     name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
24688     vim_free(fudi.fd_newkey);
24689     if (name == NULL)
24690     {
24691 	if (fudi.fd_dict != NULL && !eap->skip)
24692 	    EMSG(_(e_funcref));
24693 	return;
24694     }
24695     if (!ends_excmd(*skipwhite(p)))
24696     {
24697 	vim_free(name);
24698 	EMSG(_(e_trailing));
24699 	return;
24700     }
24701     eap->nextcmd = check_nextcmd(p);
24702     if (eap->nextcmd != NULL)
24703 	*p = NUL;
24704 
24705     if (!eap->skip)
24706 	fp = find_func(name);
24707     vim_free(name);
24708 
24709     if (!eap->skip)
24710     {
24711 	if (fp == NULL)
24712 	{
24713 	    EMSG2(_(e_nofunc), eap->arg);
24714 	    return;
24715 	}
24716 	if (fp->uf_calls > 0)
24717 	{
24718 	    EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg);
24719 	    return;
24720 	}
24721 
24722 	if (fudi.fd_dict != NULL)
24723 	{
24724 	    /* Delete the dict item that refers to the function, it will
24725 	     * invoke func_unref() and possibly delete the function. */
24726 	    dictitem_remove(fudi.fd_dict, fudi.fd_di);
24727 	}
24728 	else
24729 	    func_free(fp);
24730     }
24731 }
24732 
24733 /*
24734  * Free a function and remove it from the list of functions.
24735  */
24736     static void
24737 func_free(ufunc_T *fp)
24738 {
24739     hashitem_T	*hi;
24740 
24741     /* clear this function */
24742     ga_clear_strings(&(fp->uf_args));
24743     ga_clear_strings(&(fp->uf_lines));
24744 #ifdef FEAT_PROFILE
24745     vim_free(fp->uf_tml_count);
24746     vim_free(fp->uf_tml_total);
24747     vim_free(fp->uf_tml_self);
24748 #endif
24749 
24750     /* remove the function from the function hashtable */
24751     hi = hash_find(&func_hashtab, UF2HIKEY(fp));
24752     if (HASHITEM_EMPTY(hi))
24753 	EMSG2(_(e_intern2), "func_free()");
24754     else
24755 	hash_remove(&func_hashtab, hi);
24756 
24757     vim_free(fp);
24758 }
24759 
24760 /*
24761  * Unreference a Function: decrement the reference count and free it when it
24762  * becomes zero.  Only for numbered functions.
24763  */
24764     void
24765 func_unref(char_u *name)
24766 {
24767     ufunc_T *fp;
24768 
24769     if (name != NULL && isdigit(*name))
24770     {
24771 	fp = find_func(name);
24772 	if (fp == NULL)
24773 	    EMSG2(_(e_intern2), "func_unref()");
24774 	else if (--fp->uf_refcount <= 0)
24775 	{
24776 	    /* Only delete it when it's not being used.  Otherwise it's done
24777 	     * when "uf_calls" becomes zero. */
24778 	    if (fp->uf_calls == 0)
24779 		func_free(fp);
24780 	}
24781     }
24782 }
24783 
24784 /*
24785  * Count a reference to a Function.
24786  */
24787     void
24788 func_ref(char_u *name)
24789 {
24790     ufunc_T *fp;
24791 
24792     if (name != NULL && isdigit(*name))
24793     {
24794 	fp = find_func(name);
24795 	if (fp == NULL)
24796 	    EMSG2(_(e_intern2), "func_ref()");
24797 	else
24798 	    ++fp->uf_refcount;
24799     }
24800 }
24801 
24802 /*
24803  * Call a user function.
24804  */
24805     static void
24806 call_user_func(
24807     ufunc_T	*fp,		/* pointer to function */
24808     int		argcount,	/* nr of args */
24809     typval_T	*argvars,	/* arguments */
24810     typval_T	*rettv,		/* return value */
24811     linenr_T	firstline,	/* first line of range */
24812     linenr_T	lastline,	/* last line of range */
24813     dict_T	*selfdict)	/* Dictionary for "self" */
24814 {
24815     char_u	*save_sourcing_name;
24816     linenr_T	save_sourcing_lnum;
24817     scid_T	save_current_SID;
24818     funccall_T	*fc;
24819     int		save_did_emsg;
24820     static int	depth = 0;
24821     dictitem_T	*v;
24822     int		fixvar_idx = 0;	/* index in fixvar[] */
24823     int		i;
24824     int		ai;
24825     char_u	numbuf[NUMBUFLEN];
24826     char_u	*name;
24827     size_t	len;
24828 #ifdef FEAT_PROFILE
24829     proftime_T	wait_start;
24830     proftime_T	call_start;
24831 #endif
24832 
24833     /* If depth of calling is getting too high, don't execute the function */
24834     if (depth >= p_mfd)
24835     {
24836 	EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'"));
24837 	rettv->v_type = VAR_NUMBER;
24838 	rettv->vval.v_number = -1;
24839 	return;
24840     }
24841     ++depth;
24842 
24843     line_breakcheck();		/* check for CTRL-C hit */
24844 
24845     fc = (funccall_T *)alloc(sizeof(funccall_T));
24846     fc->caller = current_funccal;
24847     current_funccal = fc;
24848     fc->func = fp;
24849     fc->rettv = rettv;
24850     rettv->vval.v_number = 0;
24851     fc->linenr = 0;
24852     fc->returned = FALSE;
24853     fc->level = ex_nesting_level;
24854     /* Check if this function has a breakpoint. */
24855     fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
24856     fc->dbg_tick = debug_tick;
24857 
24858     /*
24859      * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
24860      * with names up to VAR_SHORT_LEN long.  This avoids having to alloc/free
24861      * each argument variable and saves a lot of time.
24862      */
24863     /*
24864      * Init l: variables.
24865      */
24866     init_var_dict(&fc->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE);
24867     if (selfdict != NULL)
24868     {
24869 	/* Set l:self to "selfdict".  Use "name" to avoid a warning from
24870 	 * some compiler that checks the destination size. */
24871 	v = &fc->fixvar[fixvar_idx++].var;
24872 	name = v->di_key;
24873 	STRCPY(name, "self");
24874 	v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX;
24875 	hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v));
24876 	v->di_tv.v_type = VAR_DICT;
24877 	v->di_tv.v_lock = 0;
24878 	v->di_tv.vval.v_dict = selfdict;
24879 	++selfdict->dv_refcount;
24880     }
24881 
24882     /*
24883      * Init a: variables.
24884      * Set a:0 to "argcount".
24885      * Set a:000 to a list with room for the "..." arguments.
24886      */
24887     init_var_dict(&fc->l_avars, &fc->l_avars_var, VAR_SCOPE);
24888     add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0",
24889 				(varnumber_T)(argcount - fp->uf_args.ga_len));
24890     /* Use "name" to avoid a warning from some compiler that checks the
24891      * destination size. */
24892     v = &fc->fixvar[fixvar_idx++].var;
24893     name = v->di_key;
24894     STRCPY(name, "000");
24895     v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
24896     hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
24897     v->di_tv.v_type = VAR_LIST;
24898     v->di_tv.v_lock = VAR_FIXED;
24899     v->di_tv.vval.v_list = &fc->l_varlist;
24900     vim_memset(&fc->l_varlist, 0, sizeof(list_T));
24901     fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT;
24902     fc->l_varlist.lv_lock = VAR_FIXED;
24903 
24904     /*
24905      * Set a:firstline to "firstline" and a:lastline to "lastline".
24906      * Set a:name to named arguments.
24907      * Set a:N to the "..." arguments.
24908      */
24909     add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline",
24910 						      (varnumber_T)firstline);
24911     add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline",
24912 						       (varnumber_T)lastline);
24913     for (i = 0; i < argcount; ++i)
24914     {
24915 	ai = i - fp->uf_args.ga_len;
24916 	if (ai < 0)
24917 	    /* named argument a:name */
24918 	    name = FUNCARG(fp, i);
24919 	else
24920 	{
24921 	    /* "..." argument a:1, a:2, etc. */
24922 	    sprintf((char *)numbuf, "%d", ai + 1);
24923 	    name = numbuf;
24924 	}
24925 	if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN)
24926 	{
24927 	    v = &fc->fixvar[fixvar_idx++].var;
24928 	    v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
24929 	}
24930 	else
24931 	{
24932 	    v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
24933 							     + STRLEN(name)));
24934 	    if (v == NULL)
24935 		break;
24936 	    v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX | DI_FLAGS_ALLOC;
24937 	}
24938 	STRCPY(v->di_key, name);
24939 	hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
24940 
24941 	/* Note: the values are copied directly to avoid alloc/free.
24942 	 * "argvars" must have VAR_FIXED for v_lock. */
24943 	v->di_tv = argvars[i];
24944 	v->di_tv.v_lock = VAR_FIXED;
24945 
24946 	if (ai >= 0 && ai < MAX_FUNC_ARGS)
24947 	{
24948 	    list_append(&fc->l_varlist, &fc->l_listitems[ai]);
24949 	    fc->l_listitems[ai].li_tv = argvars[i];
24950 	    fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED;
24951 	}
24952     }
24953 
24954     /* Don't redraw while executing the function. */
24955     ++RedrawingDisabled;
24956     save_sourcing_name = sourcing_name;
24957     save_sourcing_lnum = sourcing_lnum;
24958     sourcing_lnum = 1;
24959     /* need space for function name + ("function " + 3) or "[number]" */
24960     len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name))
24961 						   + STRLEN(fp->uf_name) + 20;
24962     sourcing_name = alloc((unsigned)len);
24963     if (sourcing_name != NULL)
24964     {
24965 	if (save_sourcing_name != NULL
24966 			  && STRNCMP(save_sourcing_name, "function ", 9) == 0)
24967 	    sprintf((char *)sourcing_name, "%s[%d]..",
24968 				 save_sourcing_name, (int)save_sourcing_lnum);
24969 	else
24970 	    STRCPY(sourcing_name, "function ");
24971 	cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
24972 
24973 	if (p_verbose >= 12)
24974 	{
24975 	    ++no_wait_return;
24976 	    verbose_enter_scroll();
24977 
24978 	    smsg((char_u *)_("calling %s"), sourcing_name);
24979 	    if (p_verbose >= 14)
24980 	    {
24981 		char_u	buf[MSG_BUF_LEN];
24982 		char_u	numbuf2[NUMBUFLEN];
24983 		char_u	*tofree;
24984 		char_u	*s;
24985 
24986 		msg_puts((char_u *)"(");
24987 		for (i = 0; i < argcount; ++i)
24988 		{
24989 		    if (i > 0)
24990 			msg_puts((char_u *)", ");
24991 		    if (argvars[i].v_type == VAR_NUMBER)
24992 			msg_outnum((long)argvars[i].vval.v_number);
24993 		    else
24994 		    {
24995 			/* Do not want errors such as E724 here. */
24996 			++emsg_off;
24997 			s = tv2string(&argvars[i], &tofree, numbuf2, 0);
24998 			--emsg_off;
24999 			if (s != NULL)
25000 			{
25001 			    if (vim_strsize(s) > MSG_BUF_CLEN)
25002 			    {
25003 				trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
25004 				s = buf;
25005 			    }
25006 			    msg_puts(s);
25007 			    vim_free(tofree);
25008 			}
25009 		    }
25010 		}
25011 		msg_puts((char_u *)")");
25012 	    }
25013 	    msg_puts((char_u *)"\n");   /* don't overwrite this either */
25014 
25015 	    verbose_leave_scroll();
25016 	    --no_wait_return;
25017 	}
25018     }
25019 #ifdef FEAT_PROFILE
25020     if (do_profiling == PROF_YES)
25021     {
25022 	if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL))
25023 	    func_do_profile(fp);
25024 	if (fp->uf_profiling
25025 		    || (fc->caller != NULL && fc->caller->func->uf_profiling))
25026 	{
25027 	    ++fp->uf_tm_count;
25028 	    profile_start(&call_start);
25029 	    profile_zero(&fp->uf_tm_children);
25030 	}
25031 	script_prof_save(&wait_start);
25032     }
25033 #endif
25034 
25035     save_current_SID = current_SID;
25036     current_SID = fp->uf_script_ID;
25037     save_did_emsg = did_emsg;
25038     did_emsg = FALSE;
25039 
25040     /* call do_cmdline() to execute the lines */
25041     do_cmdline(NULL, get_func_line, (void *)fc,
25042 				     DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
25043 
25044     --RedrawingDisabled;
25045 
25046     /* when the function was aborted because of an error, return -1 */
25047     if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN)
25048     {
25049 	clear_tv(rettv);
25050 	rettv->v_type = VAR_NUMBER;
25051 	rettv->vval.v_number = -1;
25052     }
25053 
25054 #ifdef FEAT_PROFILE
25055     if (do_profiling == PROF_YES && (fp->uf_profiling
25056 		    || (fc->caller != NULL && fc->caller->func->uf_profiling)))
25057     {
25058 	profile_end(&call_start);
25059 	profile_sub_wait(&wait_start, &call_start);
25060 	profile_add(&fp->uf_tm_total, &call_start);
25061 	profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children);
25062 	if (fc->caller != NULL && fc->caller->func->uf_profiling)
25063 	{
25064 	    profile_add(&fc->caller->func->uf_tm_children, &call_start);
25065 	    profile_add(&fc->caller->func->uf_tml_children, &call_start);
25066 	}
25067     }
25068 #endif
25069 
25070     /* when being verbose, mention the return value */
25071     if (p_verbose >= 12)
25072     {
25073 	++no_wait_return;
25074 	verbose_enter_scroll();
25075 
25076 	if (aborting())
25077 	    smsg((char_u *)_("%s aborted"), sourcing_name);
25078 	else if (fc->rettv->v_type == VAR_NUMBER)
25079 	    smsg((char_u *)_("%s returning #%ld"), sourcing_name,
25080 					       (long)fc->rettv->vval.v_number);
25081 	else
25082 	{
25083 	    char_u	buf[MSG_BUF_LEN];
25084 	    char_u	numbuf2[NUMBUFLEN];
25085 	    char_u	*tofree;
25086 	    char_u	*s;
25087 
25088 	    /* The value may be very long.  Skip the middle part, so that we
25089 	     * have some idea how it starts and ends. smsg() would always
25090 	     * truncate it at the end. Don't want errors such as E724 here. */
25091 	    ++emsg_off;
25092 	    s = tv2string(fc->rettv, &tofree, numbuf2, 0);
25093 	    --emsg_off;
25094 	    if (s != NULL)
25095 	    {
25096 		if (vim_strsize(s) > MSG_BUF_CLEN)
25097 		{
25098 		    trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
25099 		    s = buf;
25100 		}
25101 		smsg((char_u *)_("%s returning %s"), sourcing_name, s);
25102 		vim_free(tofree);
25103 	    }
25104 	}
25105 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
25106 
25107 	verbose_leave_scroll();
25108 	--no_wait_return;
25109     }
25110 
25111     vim_free(sourcing_name);
25112     sourcing_name = save_sourcing_name;
25113     sourcing_lnum = save_sourcing_lnum;
25114     current_SID = save_current_SID;
25115 #ifdef FEAT_PROFILE
25116     if (do_profiling == PROF_YES)
25117 	script_prof_restore(&wait_start);
25118 #endif
25119 
25120     if (p_verbose >= 12 && sourcing_name != NULL)
25121     {
25122 	++no_wait_return;
25123 	verbose_enter_scroll();
25124 
25125 	smsg((char_u *)_("continuing in %s"), sourcing_name);
25126 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
25127 
25128 	verbose_leave_scroll();
25129 	--no_wait_return;
25130     }
25131 
25132     did_emsg |= save_did_emsg;
25133     current_funccal = fc->caller;
25134     --depth;
25135 
25136     /* If the a:000 list and the l: and a: dicts are not referenced we can
25137      * free the funccall_T and what's in it. */
25138     if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
25139 	    && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
25140 	    && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
25141     {
25142 	free_funccal(fc, FALSE);
25143     }
25144     else
25145     {
25146 	hashitem_T	*hi;
25147 	listitem_T	*li;
25148 	int		todo;
25149 
25150 	/* "fc" is still in use.  This can happen when returning "a:000" or
25151 	 * assigning "l:" to a global variable.
25152 	 * Link "fc" in the list for garbage collection later. */
25153 	fc->caller = previous_funccal;
25154 	previous_funccal = fc;
25155 
25156 	/* Make a copy of the a: variables, since we didn't do that above. */
25157 	todo = (int)fc->l_avars.dv_hashtab.ht_used;
25158 	for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
25159 	{
25160 	    if (!HASHITEM_EMPTY(hi))
25161 	    {
25162 		--todo;
25163 		v = HI2DI(hi);
25164 		copy_tv(&v->di_tv, &v->di_tv);
25165 	    }
25166 	}
25167 
25168 	/* Make a copy of the a:000 items, since we didn't do that above. */
25169 	for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
25170 	    copy_tv(&li->li_tv, &li->li_tv);
25171     }
25172 }
25173 
25174 /*
25175  * Return TRUE if items in "fc" do not have "copyID".  That means they are not
25176  * referenced from anywhere that is in use.
25177  */
25178     static int
25179 can_free_funccal(funccall_T *fc, int copyID)
25180 {
25181     return (fc->l_varlist.lv_copyID != copyID
25182 	    && fc->l_vars.dv_copyID != copyID
25183 	    && fc->l_avars.dv_copyID != copyID);
25184 }
25185 
25186 /*
25187  * Free "fc" and what it contains.
25188  */
25189    static void
25190 free_funccal(
25191     funccall_T	*fc,
25192     int		free_val)  /* a: vars were allocated */
25193 {
25194     listitem_T	*li;
25195 
25196     /* The a: variables typevals may not have been allocated, only free the
25197      * allocated variables. */
25198     vars_clear_ext(&fc->l_avars.dv_hashtab, free_val);
25199 
25200     /* free all l: variables */
25201     vars_clear(&fc->l_vars.dv_hashtab);
25202 
25203     /* Free the a:000 variables if they were allocated. */
25204     if (free_val)
25205 	for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
25206 	    clear_tv(&li->li_tv);
25207 
25208     vim_free(fc);
25209 }
25210 
25211 /*
25212  * Add a number variable "name" to dict "dp" with value "nr".
25213  */
25214     static void
25215 add_nr_var(
25216     dict_T	*dp,
25217     dictitem_T	*v,
25218     char	*name,
25219     varnumber_T nr)
25220 {
25221     STRCPY(v->di_key, name);
25222     v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
25223     hash_add(&dp->dv_hashtab, DI2HIKEY(v));
25224     v->di_tv.v_type = VAR_NUMBER;
25225     v->di_tv.v_lock = VAR_FIXED;
25226     v->di_tv.vval.v_number = nr;
25227 }
25228 
25229 /*
25230  * ":return [expr]"
25231  */
25232     void
25233 ex_return(exarg_T *eap)
25234 {
25235     char_u	*arg = eap->arg;
25236     typval_T	rettv;
25237     int		returning = FALSE;
25238 
25239     if (current_funccal == NULL)
25240     {
25241 	EMSG(_("E133: :return not inside a function"));
25242 	return;
25243     }
25244 
25245     if (eap->skip)
25246 	++emsg_skip;
25247 
25248     eap->nextcmd = NULL;
25249     if ((*arg != NUL && *arg != '|' && *arg != '\n')
25250 	    && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL)
25251     {
25252 	if (!eap->skip)
25253 	    returning = do_return(eap, FALSE, TRUE, &rettv);
25254 	else
25255 	    clear_tv(&rettv);
25256     }
25257     /* It's safer to return also on error. */
25258     else if (!eap->skip)
25259     {
25260 	/*
25261 	 * Return unless the expression evaluation has been cancelled due to an
25262 	 * aborting error, an interrupt, or an exception.
25263 	 */
25264 	if (!aborting())
25265 	    returning = do_return(eap, FALSE, TRUE, NULL);
25266     }
25267 
25268     /* When skipping or the return gets pending, advance to the next command
25269      * in this line (!returning).  Otherwise, ignore the rest of the line.
25270      * Following lines will be ignored by get_func_line(). */
25271     if (returning)
25272 	eap->nextcmd = NULL;
25273     else if (eap->nextcmd == NULL)	    /* no argument */
25274 	eap->nextcmd = check_nextcmd(arg);
25275 
25276     if (eap->skip)
25277 	--emsg_skip;
25278 }
25279 
25280 /*
25281  * Return from a function.  Possibly makes the return pending.  Also called
25282  * for a pending return at the ":endtry" or after returning from an extra
25283  * do_cmdline().  "reanimate" is used in the latter case.  "is_cmd" is set
25284  * when called due to a ":return" command.  "rettv" may point to a typval_T
25285  * with the return rettv.  Returns TRUE when the return can be carried out,
25286  * FALSE when the return gets pending.
25287  */
25288     int
25289 do_return(
25290     exarg_T	*eap,
25291     int		reanimate,
25292     int		is_cmd,
25293     void	*rettv)
25294 {
25295     int		idx;
25296     struct condstack *cstack = eap->cstack;
25297 
25298     if (reanimate)
25299 	/* Undo the return. */
25300 	current_funccal->returned = FALSE;
25301 
25302     /*
25303      * Cleanup (and inactivate) conditionals, but stop when a try conditional
25304      * not in its finally clause (which then is to be executed next) is found.
25305      * In this case, make the ":return" pending for execution at the ":endtry".
25306      * Otherwise, return normally.
25307      */
25308     idx = cleanup_conditionals(eap->cstack, 0, TRUE);
25309     if (idx >= 0)
25310     {
25311 	cstack->cs_pending[idx] = CSTP_RETURN;
25312 
25313 	if (!is_cmd && !reanimate)
25314 	    /* A pending return again gets pending.  "rettv" points to an
25315 	     * allocated variable with the rettv of the original ":return"'s
25316 	     * argument if present or is NULL else. */
25317 	    cstack->cs_rettv[idx] = rettv;
25318 	else
25319 	{
25320 	    /* When undoing a return in order to make it pending, get the stored
25321 	     * return rettv. */
25322 	    if (reanimate)
25323 		rettv = current_funccal->rettv;
25324 
25325 	    if (rettv != NULL)
25326 	    {
25327 		/* Store the value of the pending return. */
25328 		if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL)
25329 		    *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
25330 		else
25331 		    EMSG(_(e_outofmem));
25332 	    }
25333 	    else
25334 		cstack->cs_rettv[idx] = NULL;
25335 
25336 	    if (reanimate)
25337 	    {
25338 		/* The pending return value could be overwritten by a ":return"
25339 		 * without argument in a finally clause; reset the default
25340 		 * return value. */
25341 		current_funccal->rettv->v_type = VAR_NUMBER;
25342 		current_funccal->rettv->vval.v_number = 0;
25343 	    }
25344 	}
25345 	report_make_pending(CSTP_RETURN, rettv);
25346     }
25347     else
25348     {
25349 	current_funccal->returned = TRUE;
25350 
25351 	/* If the return is carried out now, store the return value.  For
25352 	 * a return immediately after reanimation, the value is already
25353 	 * there. */
25354 	if (!reanimate && rettv != NULL)
25355 	{
25356 	    clear_tv(current_funccal->rettv);
25357 	    *current_funccal->rettv = *(typval_T *)rettv;
25358 	    if (!is_cmd)
25359 		vim_free(rettv);
25360 	}
25361     }
25362 
25363     return idx < 0;
25364 }
25365 
25366 /*
25367  * Free the variable with a pending return value.
25368  */
25369     void
25370 discard_pending_return(void *rettv)
25371 {
25372     free_tv((typval_T *)rettv);
25373 }
25374 
25375 /*
25376  * Generate a return command for producing the value of "rettv".  The result
25377  * is an allocated string.  Used by report_pending() for verbose messages.
25378  */
25379     char_u *
25380 get_return_cmd(void *rettv)
25381 {
25382     char_u	*s = NULL;
25383     char_u	*tofree = NULL;
25384     char_u	numbuf[NUMBUFLEN];
25385 
25386     if (rettv != NULL)
25387 	s = echo_string((typval_T *)rettv, &tofree, numbuf, 0);
25388     if (s == NULL)
25389 	s = (char_u *)"";
25390 
25391     STRCPY(IObuff, ":return ");
25392     STRNCPY(IObuff + 8, s, IOSIZE - 8);
25393     if (STRLEN(s) + 8 >= IOSIZE)
25394 	STRCPY(IObuff + IOSIZE - 4, "...");
25395     vim_free(tofree);
25396     return vim_strsave(IObuff);
25397 }
25398 
25399 /*
25400  * Get next function line.
25401  * Called by do_cmdline() to get the next line.
25402  * Returns allocated string, or NULL for end of function.
25403  */
25404     char_u *
25405 get_func_line(
25406     int	    c UNUSED,
25407     void    *cookie,
25408     int	    indent UNUSED)
25409 {
25410     funccall_T	*fcp = (funccall_T *)cookie;
25411     ufunc_T	*fp = fcp->func;
25412     char_u	*retval;
25413     garray_T	*gap;  /* growarray with function lines */
25414 
25415     /* If breakpoints have been added/deleted need to check for it. */
25416     if (fcp->dbg_tick != debug_tick)
25417     {
25418 	fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
25419 							       sourcing_lnum);
25420 	fcp->dbg_tick = debug_tick;
25421     }
25422 #ifdef FEAT_PROFILE
25423     if (do_profiling == PROF_YES)
25424 	func_line_end(cookie);
25425 #endif
25426 
25427     gap = &fp->uf_lines;
25428     if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
25429 	    || fcp->returned)
25430 	retval = NULL;
25431     else
25432     {
25433 	/* Skip NULL lines (continuation lines). */
25434 	while (fcp->linenr < gap->ga_len
25435 			  && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL)
25436 	    ++fcp->linenr;
25437 	if (fcp->linenr >= gap->ga_len)
25438 	    retval = NULL;
25439 	else
25440 	{
25441 	    retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
25442 	    sourcing_lnum = fcp->linenr;
25443 #ifdef FEAT_PROFILE
25444 	    if (do_profiling == PROF_YES)
25445 		func_line_start(cookie);
25446 #endif
25447 	}
25448     }
25449 
25450     /* Did we encounter a breakpoint? */
25451     if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum)
25452     {
25453 	dbg_breakpoint(fp->uf_name, sourcing_lnum);
25454 	/* Find next breakpoint. */
25455 	fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
25456 							       sourcing_lnum);
25457 	fcp->dbg_tick = debug_tick;
25458     }
25459 
25460     return retval;
25461 }
25462 
25463 #if defined(FEAT_PROFILE) || defined(PROTO)
25464 /*
25465  * Called when starting to read a function line.
25466  * "sourcing_lnum" must be correct!
25467  * When skipping lines it may not actually be executed, but we won't find out
25468  * until later and we need to store the time now.
25469  */
25470     void
25471 func_line_start(void *cookie)
25472 {
25473     funccall_T	*fcp = (funccall_T *)cookie;
25474     ufunc_T	*fp = fcp->func;
25475 
25476     if (fp->uf_profiling && sourcing_lnum >= 1
25477 				      && sourcing_lnum <= fp->uf_lines.ga_len)
25478     {
25479 	fp->uf_tml_idx = sourcing_lnum - 1;
25480 	/* Skip continuation lines. */
25481 	while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
25482 	    --fp->uf_tml_idx;
25483 	fp->uf_tml_execed = FALSE;
25484 	profile_start(&fp->uf_tml_start);
25485 	profile_zero(&fp->uf_tml_children);
25486 	profile_get_wait(&fp->uf_tml_wait);
25487     }
25488 }
25489 
25490 /*
25491  * Called when actually executing a function line.
25492  */
25493     void
25494 func_line_exec(void *cookie)
25495 {
25496     funccall_T	*fcp = (funccall_T *)cookie;
25497     ufunc_T	*fp = fcp->func;
25498 
25499     if (fp->uf_profiling && fp->uf_tml_idx >= 0)
25500 	fp->uf_tml_execed = TRUE;
25501 }
25502 
25503 /*
25504  * Called when done with a function line.
25505  */
25506     void
25507 func_line_end(void *cookie)
25508 {
25509     funccall_T	*fcp = (funccall_T *)cookie;
25510     ufunc_T	*fp = fcp->func;
25511 
25512     if (fp->uf_profiling && fp->uf_tml_idx >= 0)
25513     {
25514 	if (fp->uf_tml_execed)
25515 	{
25516 	    ++fp->uf_tml_count[fp->uf_tml_idx];
25517 	    profile_end(&fp->uf_tml_start);
25518 	    profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start);
25519 	    profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start);
25520 	    profile_self(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start,
25521 							&fp->uf_tml_children);
25522 	}
25523 	fp->uf_tml_idx = -1;
25524     }
25525 }
25526 #endif
25527 
25528 /*
25529  * Return TRUE if the currently active function should be ended, because a
25530  * return was encountered or an error occurred.  Used inside a ":while".
25531  */
25532     int
25533 func_has_ended(void *cookie)
25534 {
25535     funccall_T  *fcp = (funccall_T *)cookie;
25536 
25537     /* Ignore the "abort" flag if the abortion behavior has been changed due to
25538      * an error inside a try conditional. */
25539     return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
25540 	    || fcp->returned);
25541 }
25542 
25543 /*
25544  * return TRUE if cookie indicates a function which "abort"s on errors.
25545  */
25546     int
25547 func_has_abort(
25548     void    *cookie)
25549 {
25550     return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT;
25551 }
25552 
25553 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)
25554 typedef enum
25555 {
25556     VAR_FLAVOUR_DEFAULT,	/* doesn't start with uppercase */
25557     VAR_FLAVOUR_SESSION,	/* starts with uppercase, some lower */
25558     VAR_FLAVOUR_VIMINFO		/* all uppercase */
25559 } var_flavour_T;
25560 
25561 static var_flavour_T var_flavour(char_u *varname);
25562 
25563     static var_flavour_T
25564 var_flavour(char_u *varname)
25565 {
25566     char_u *p = varname;
25567 
25568     if (ASCII_ISUPPER(*p))
25569     {
25570 	while (*(++p))
25571 	    if (ASCII_ISLOWER(*p))
25572 		return VAR_FLAVOUR_SESSION;
25573 	return VAR_FLAVOUR_VIMINFO;
25574     }
25575     else
25576 	return VAR_FLAVOUR_DEFAULT;
25577 }
25578 #endif
25579 
25580 #if defined(FEAT_VIMINFO) || defined(PROTO)
25581 /*
25582  * Restore global vars that start with a capital from the viminfo file
25583  */
25584     int
25585 read_viminfo_varlist(vir_T *virp, int writing)
25586 {
25587     char_u	*tab;
25588     int		type = VAR_NUMBER;
25589     typval_T	tv;
25590     funccall_T  *save_funccal;
25591 
25592     if (!writing && (find_viminfo_parameter('!') != NULL))
25593     {
25594 	tab = vim_strchr(virp->vir_line + 1, '\t');
25595 	if (tab != NULL)
25596 	{
25597 	    *tab++ = '\0';	/* isolate the variable name */
25598 	    switch (*tab)
25599 	    {
25600 		case 'S': type = VAR_STRING; break;
25601 #ifdef FEAT_FLOAT
25602 		case 'F': type = VAR_FLOAT; break;
25603 #endif
25604 		case 'D': type = VAR_DICT; break;
25605 		case 'L': type = VAR_LIST; break;
25606 		case 'X': type = VAR_SPECIAL; break;
25607 	    }
25608 
25609 	    tab = vim_strchr(tab, '\t');
25610 	    if (tab != NULL)
25611 	    {
25612 		tv.v_type = type;
25613 		if (type == VAR_STRING || type == VAR_DICT || type == VAR_LIST)
25614 		    tv.vval.v_string = viminfo_readstring(virp,
25615 				       (int)(tab - virp->vir_line + 1), TRUE);
25616 #ifdef FEAT_FLOAT
25617 		else if (type == VAR_FLOAT)
25618 		    (void)string2float(tab + 1, &tv.vval.v_float);
25619 #endif
25620 		else
25621 		    tv.vval.v_number = atol((char *)tab + 1);
25622 		if (type == VAR_DICT || type == VAR_LIST)
25623 		{
25624 		    typval_T *etv = eval_expr(tv.vval.v_string, NULL);
25625 
25626 		    if (etv == NULL)
25627 			/* Failed to parse back the dict or list, use it as a
25628 			 * string. */
25629 			tv.v_type = VAR_STRING;
25630 		    else
25631 		    {
25632 			vim_free(tv.vval.v_string);
25633 			tv = *etv;
25634 			vim_free(etv);
25635 		    }
25636 		}
25637 
25638 		/* when in a function use global variables */
25639 		save_funccal = current_funccal;
25640 		current_funccal = NULL;
25641 		set_var(virp->vir_line + 1, &tv, FALSE);
25642 		current_funccal = save_funccal;
25643 
25644 		if (tv.v_type == VAR_STRING)
25645 		    vim_free(tv.vval.v_string);
25646 		else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST)
25647 		    clear_tv(&tv);
25648 	    }
25649 	}
25650     }
25651 
25652     return viminfo_readline(virp);
25653 }
25654 
25655 /*
25656  * Write global vars that start with a capital to the viminfo file
25657  */
25658     void
25659 write_viminfo_varlist(FILE *fp)
25660 {
25661     hashitem_T	*hi;
25662     dictitem_T	*this_var;
25663     int		todo;
25664     char	*s = "";
25665     char_u	*p;
25666     char_u	*tofree;
25667     char_u	numbuf[NUMBUFLEN];
25668 
25669     if (find_viminfo_parameter('!') == NULL)
25670 	return;
25671 
25672     fputs(_("\n# global variables:\n"), fp);
25673 
25674     todo = (int)globvarht.ht_used;
25675     for (hi = globvarht.ht_array; todo > 0; ++hi)
25676     {
25677 	if (!HASHITEM_EMPTY(hi))
25678 	{
25679 	    --todo;
25680 	    this_var = HI2DI(hi);
25681 	    if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO)
25682 	    {
25683 		switch (this_var->di_tv.v_type)
25684 		{
25685 		    case VAR_STRING: s = "STR"; break;
25686 		    case VAR_NUMBER: s = "NUM"; break;
25687 		    case VAR_FLOAT:  s = "FLO"; break;
25688 		    case VAR_DICT:   s = "DIC"; break;
25689 		    case VAR_LIST:   s = "LIS"; break;
25690 		    case VAR_SPECIAL: s = "XPL"; break;
25691 
25692 		    case VAR_UNKNOWN:
25693 		    case VAR_FUNC:
25694 		    case VAR_PARTIAL:
25695 		    case VAR_JOB:
25696 		    case VAR_CHANNEL:
25697 				     continue;
25698 		}
25699 		fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
25700 		p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
25701 		if (p != NULL)
25702 		    viminfo_writestring(fp, p);
25703 		vim_free(tofree);
25704 	    }
25705 	}
25706     }
25707 }
25708 #endif
25709 
25710 #if defined(FEAT_SESSION) || defined(PROTO)
25711     int
25712 store_session_globals(FILE *fd)
25713 {
25714     hashitem_T	*hi;
25715     dictitem_T	*this_var;
25716     int		todo;
25717     char_u	*p, *t;
25718 
25719     todo = (int)globvarht.ht_used;
25720     for (hi = globvarht.ht_array; todo > 0; ++hi)
25721     {
25722 	if (!HASHITEM_EMPTY(hi))
25723 	{
25724 	    --todo;
25725 	    this_var = HI2DI(hi);
25726 	    if ((this_var->di_tv.v_type == VAR_NUMBER
25727 			|| this_var->di_tv.v_type == VAR_STRING)
25728 		    && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION)
25729 	    {
25730 		/* Escape special characters with a backslash.  Turn a LF and
25731 		 * CR into \n and \r. */
25732 		p = vim_strsave_escaped(get_tv_string(&this_var->di_tv),
25733 							(char_u *)"\\\"\n\r");
25734 		if (p == NULL)	    /* out of memory */
25735 		    break;
25736 		for (t = p; *t != NUL; ++t)
25737 		    if (*t == '\n')
25738 			*t = 'n';
25739 		    else if (*t == '\r')
25740 			*t = 'r';
25741 		if ((fprintf(fd, "let %s = %c%s%c",
25742 				this_var->di_key,
25743 				(this_var->di_tv.v_type == VAR_STRING) ? '"'
25744 									: ' ',
25745 				p,
25746 				(this_var->di_tv.v_type == VAR_STRING) ? '"'
25747 								   : ' ') < 0)
25748 			|| put_eol(fd) == FAIL)
25749 		{
25750 		    vim_free(p);
25751 		    return FAIL;
25752 		}
25753 		vim_free(p);
25754 	    }
25755 #ifdef FEAT_FLOAT
25756 	    else if (this_var->di_tv.v_type == VAR_FLOAT
25757 		    && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION)
25758 	    {
25759 		float_T f = this_var->di_tv.vval.v_float;
25760 		int sign = ' ';
25761 
25762 		if (f < 0)
25763 		{
25764 		    f = -f;
25765 		    sign = '-';
25766 		}
25767 		if ((fprintf(fd, "let %s = %c%f",
25768 					       this_var->di_key, sign, f) < 0)
25769 			|| put_eol(fd) == FAIL)
25770 		    return FAIL;
25771 	    }
25772 #endif
25773 	}
25774     }
25775     return OK;
25776 }
25777 #endif
25778 
25779 /*
25780  * Display script name where an item was last set.
25781  * Should only be invoked when 'verbose' is non-zero.
25782  */
25783     void
25784 last_set_msg(scid_T scriptID)
25785 {
25786     char_u *p;
25787 
25788     if (scriptID != 0)
25789     {
25790 	p = home_replace_save(NULL, get_scriptname(scriptID));
25791 	if (p != NULL)
25792 	{
25793 	    verbose_enter();
25794 	    MSG_PUTS(_("\n\tLast set from "));
25795 	    MSG_PUTS(p);
25796 	    vim_free(p);
25797 	    verbose_leave();
25798 	}
25799     }
25800 }
25801 
25802 /*
25803  * List v:oldfiles in a nice way.
25804  */
25805     void
25806 ex_oldfiles(exarg_T *eap UNUSED)
25807 {
25808     list_T	*l = vimvars[VV_OLDFILES].vv_list;
25809     listitem_T	*li;
25810     int		nr = 0;
25811 
25812     if (l == NULL)
25813 	msg((char_u *)_("No old files"));
25814     else
25815     {
25816 	msg_start();
25817 	msg_scroll = TRUE;
25818 	for (li = l->lv_first; li != NULL && !got_int; li = li->li_next)
25819 	{
25820 	    msg_outnum((long)++nr);
25821 	    MSG_PUTS(": ");
25822 	    msg_outtrans(get_tv_string(&li->li_tv));
25823 	    msg_putchar('\n');
25824 	    out_flush();	    /* output one line at a time */
25825 	    ui_breakcheck();
25826 	}
25827 	/* Assume "got_int" was set to truncate the listing. */
25828 	got_int = FALSE;
25829 
25830 #ifdef FEAT_BROWSE_CMD
25831 	if (cmdmod.browse)
25832 	{
25833 	    quit_more = FALSE;
25834 	    nr = prompt_for_number(FALSE);
25835 	    msg_starthere();
25836 	    if (nr > 0)
25837 	    {
25838 		char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES),
25839 								    (long)nr);
25840 
25841 		if (p != NULL)
25842 		{
25843 		    p = expand_env_save(p);
25844 		    eap->arg = p;
25845 		    eap->cmdidx = CMD_edit;
25846 		    cmdmod.browse = FALSE;
25847 		    do_exedit(eap, NULL);
25848 		    vim_free(p);
25849 		}
25850 	    }
25851 	}
25852 #endif
25853     }
25854 }
25855 
25856 /* reset v:option_new, v:option_old and v:option_type */
25857     void
25858 reset_v_option_vars(void)
25859 {
25860     set_vim_var_string(VV_OPTION_NEW,  NULL, -1);
25861     set_vim_var_string(VV_OPTION_OLD,  NULL, -1);
25862     set_vim_var_string(VV_OPTION_TYPE, NULL, -1);
25863 }
25864 
25865 
25866 #endif /* FEAT_EVAL */
25867 
25868 
25869 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO)
25870 
25871 #ifdef WIN3264
25872 /*
25873  * Functions for ":8" filename modifier: get 8.3 version of a filename.
25874  */
25875 static int get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen);
25876 static int shortpath_for_invalid_fname(char_u **fname, char_u **bufp, int *fnamelen);
25877 static int shortpath_for_partial(char_u **fnamep, char_u **bufp, int *fnamelen);
25878 
25879 /*
25880  * Get the short path (8.3) for the filename in "fnamep".
25881  * Only works for a valid file name.
25882  * When the path gets longer "fnamep" is changed and the allocated buffer
25883  * is put in "bufp".
25884  * *fnamelen is the length of "fnamep" and set to 0 for a nonexistent path.
25885  * Returns OK on success, FAIL on failure.
25886  */
25887     static int
25888 get_short_pathname(char_u **fnamep, char_u **bufp, int *fnamelen)
25889 {
25890     int		l, len;
25891     char_u	*newbuf;
25892 
25893     len = *fnamelen;
25894     l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, len);
25895     if (l > len - 1)
25896     {
25897 	/* If that doesn't work (not enough space), then save the string
25898 	 * and try again with a new buffer big enough. */
25899 	newbuf = vim_strnsave(*fnamep, l);
25900 	if (newbuf == NULL)
25901 	    return FAIL;
25902 
25903 	vim_free(*bufp);
25904 	*fnamep = *bufp = newbuf;
25905 
25906 	/* Really should always succeed, as the buffer is big enough. */
25907 	l = GetShortPathName((LPSTR)*fnamep, (LPSTR)*fnamep, l+1);
25908     }
25909 
25910     *fnamelen = l;
25911     return OK;
25912 }
25913 
25914 /*
25915  * Get the short path (8.3) for the filename in "fname". The converted
25916  * path is returned in "bufp".
25917  *
25918  * Some of the directories specified in "fname" may not exist. This function
25919  * will shorten the existing directories at the beginning of the path and then
25920  * append the remaining non-existing path.
25921  *
25922  * fname - Pointer to the filename to shorten.  On return, contains the
25923  *	   pointer to the shortened pathname
25924  * bufp -  Pointer to an allocated buffer for the filename.
25925  * fnamelen - Length of the filename pointed to by fname
25926  *
25927  * Returns OK on success (or nothing done) and FAIL on failure (out of memory).
25928  */
25929     static int
25930 shortpath_for_invalid_fname(
25931     char_u	**fname,
25932     char_u	**bufp,
25933     int		*fnamelen)
25934 {
25935     char_u	*short_fname, *save_fname, *pbuf_unused;
25936     char_u	*endp, *save_endp;
25937     char_u	ch;
25938     int		old_len, len;
25939     int		new_len, sfx_len;
25940     int		retval = OK;
25941 
25942     /* Make a copy */
25943     old_len = *fnamelen;
25944     save_fname = vim_strnsave(*fname, old_len);
25945     pbuf_unused = NULL;
25946     short_fname = NULL;
25947 
25948     endp = save_fname + old_len - 1; /* Find the end of the copy */
25949     save_endp = endp;
25950 
25951     /*
25952      * Try shortening the supplied path till it succeeds by removing one
25953      * directory at a time from the tail of the path.
25954      */
25955     len = 0;
25956     for (;;)
25957     {
25958 	/* go back one path-separator */
25959 	while (endp > save_fname && !after_pathsep(save_fname, endp + 1))
25960 	    --endp;
25961 	if (endp <= save_fname)
25962 	    break;		/* processed the complete path */
25963 
25964 	/*
25965 	 * Replace the path separator with a NUL and try to shorten the
25966 	 * resulting path.
25967 	 */
25968 	ch = *endp;
25969 	*endp = 0;
25970 	short_fname = save_fname;
25971 	len = (int)STRLEN(short_fname) + 1;
25972 	if (get_short_pathname(&short_fname, &pbuf_unused, &len) == FAIL)
25973 	{
25974 	    retval = FAIL;
25975 	    goto theend;
25976 	}
25977 	*endp = ch;	/* preserve the string */
25978 
25979 	if (len > 0)
25980 	    break;	/* successfully shortened the path */
25981 
25982 	/* failed to shorten the path. Skip the path separator */
25983 	--endp;
25984     }
25985 
25986     if (len > 0)
25987     {
25988 	/*
25989 	 * Succeeded in shortening the path. Now concatenate the shortened
25990 	 * path with the remaining path at the tail.
25991 	 */
25992 
25993 	/* Compute the length of the new path. */
25994 	sfx_len = (int)(save_endp - endp) + 1;
25995 	new_len = len + sfx_len;
25996 
25997 	*fnamelen = new_len;
25998 	vim_free(*bufp);
25999 	if (new_len > old_len)
26000 	{
26001 	    /* There is not enough space in the currently allocated string,
26002 	     * copy it to a buffer big enough. */
26003 	    *fname = *bufp = vim_strnsave(short_fname, new_len);
26004 	    if (*fname == NULL)
26005 	    {
26006 		retval = FAIL;
26007 		goto theend;
26008 	    }
26009 	}
26010 	else
26011 	{
26012 	    /* Transfer short_fname to the main buffer (it's big enough),
26013 	     * unless get_short_pathname() did its work in-place. */
26014 	    *fname = *bufp = save_fname;
26015 	    if (short_fname != save_fname)
26016 		vim_strncpy(save_fname, short_fname, len);
26017 	    save_fname = NULL;
26018 	}
26019 
26020 	/* concat the not-shortened part of the path */
26021 	vim_strncpy(*fname + len, endp, sfx_len);
26022 	(*fname)[new_len] = NUL;
26023     }
26024 
26025 theend:
26026     vim_free(pbuf_unused);
26027     vim_free(save_fname);
26028 
26029     return retval;
26030 }
26031 
26032 /*
26033  * Get a pathname for a partial path.
26034  * Returns OK for success, FAIL for failure.
26035  */
26036     static int
26037 shortpath_for_partial(
26038     char_u	**fnamep,
26039     char_u	**bufp,
26040     int		*fnamelen)
26041 {
26042     int		sepcount, len, tflen;
26043     char_u	*p;
26044     char_u	*pbuf, *tfname;
26045     int		hasTilde;
26046 
26047     /* Count up the path separators from the RHS.. so we know which part
26048      * of the path to return. */
26049     sepcount = 0;
26050     for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p))
26051 	if (vim_ispathsep(*p))
26052 	    ++sepcount;
26053 
26054     /* Need full path first (use expand_env() to remove a "~/") */
26055     hasTilde = (**fnamep == '~');
26056     if (hasTilde)
26057 	pbuf = tfname = expand_env_save(*fnamep);
26058     else
26059 	pbuf = tfname = FullName_save(*fnamep, FALSE);
26060 
26061     len = tflen = (int)STRLEN(tfname);
26062 
26063     if (get_short_pathname(&tfname, &pbuf, &len) == FAIL)
26064 	return FAIL;
26065 
26066     if (len == 0)
26067     {
26068 	/* Don't have a valid filename, so shorten the rest of the
26069 	 * path if we can. This CAN give us invalid 8.3 filenames, but
26070 	 * there's not a lot of point in guessing what it might be.
26071 	 */
26072 	len = tflen;
26073 	if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == FAIL)
26074 	    return FAIL;
26075     }
26076 
26077     /* Count the paths backward to find the beginning of the desired string. */
26078     for (p = tfname + len - 1; p >= tfname; --p)
26079     {
26080 #ifdef FEAT_MBYTE
26081 	if (has_mbyte)
26082 	    p -= mb_head_off(tfname, p);
26083 #endif
26084 	if (vim_ispathsep(*p))
26085 	{
26086 	    if (sepcount == 0 || (hasTilde && sepcount == 1))
26087 		break;
26088 	    else
26089 		sepcount --;
26090 	}
26091     }
26092     if (hasTilde)
26093     {
26094 	--p;
26095 	if (p >= tfname)
26096 	    *p = '~';
26097 	else
26098 	    return FAIL;
26099     }
26100     else
26101 	++p;
26102 
26103     /* Copy in the string - p indexes into tfname - allocated at pbuf */
26104     vim_free(*bufp);
26105     *fnamelen = (int)STRLEN(p);
26106     *bufp = pbuf;
26107     *fnamep = p;
26108 
26109     return OK;
26110 }
26111 #endif /* WIN3264 */
26112 
26113 /*
26114  * Adjust a filename, according to a string of modifiers.
26115  * *fnamep must be NUL terminated when called.  When returning, the length is
26116  * determined by *fnamelen.
26117  * Returns VALID_ flags or -1 for failure.
26118  * When there is an error, *fnamep is set to NULL.
26119  */
26120     int
26121 modify_fname(
26122     char_u	*src,		/* string with modifiers */
26123     int		*usedlen,	/* characters after src that are used */
26124     char_u	**fnamep,	/* file name so far */
26125     char_u	**bufp,		/* buffer for allocated file name or NULL */
26126     int		*fnamelen)	/* length of fnamep */
26127 {
26128     int		valid = 0;
26129     char_u	*tail;
26130     char_u	*s, *p, *pbuf;
26131     char_u	dirname[MAXPATHL];
26132     int		c;
26133     int		has_fullname = 0;
26134 #ifdef WIN3264
26135     char_u	*fname_start = *fnamep;
26136     int		has_shortname = 0;
26137 #endif
26138 
26139 repeat:
26140     /* ":p" - full path/file_name */
26141     if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p')
26142     {
26143 	has_fullname = 1;
26144 
26145 	valid |= VALID_PATH;
26146 	*usedlen += 2;
26147 
26148 	/* Expand "~/path" for all systems and "~user/path" for Unix and VMS */
26149 	if ((*fnamep)[0] == '~'
26150 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME))
26151 		&& ((*fnamep)[1] == '/'
26152 # ifdef BACKSLASH_IN_FILENAME
26153 		    || (*fnamep)[1] == '\\'
26154 # endif
26155 		    || (*fnamep)[1] == NUL)
26156 
26157 #endif
26158 	   )
26159 	{
26160 	    *fnamep = expand_env_save(*fnamep);
26161 	    vim_free(*bufp);	/* free any allocated file name */
26162 	    *bufp = *fnamep;
26163 	    if (*fnamep == NULL)
26164 		return -1;
26165 	}
26166 
26167 	/* When "/." or "/.." is used: force expansion to get rid of it. */
26168 	for (p = *fnamep; *p != NUL; mb_ptr_adv(p))
26169 	{
26170 	    if (vim_ispathsep(*p)
26171 		    && p[1] == '.'
26172 		    && (p[2] == NUL
26173 			|| vim_ispathsep(p[2])
26174 			|| (p[2] == '.'
26175 			    && (p[3] == NUL || vim_ispathsep(p[3])))))
26176 		break;
26177 	}
26178 
26179 	/* FullName_save() is slow, don't use it when not needed. */
26180 	if (*p != NUL || !vim_isAbsName(*fnamep))
26181 	{
26182 	    *fnamep = FullName_save(*fnamep, *p != NUL);
26183 	    vim_free(*bufp);	/* free any allocated file name */
26184 	    *bufp = *fnamep;
26185 	    if (*fnamep == NULL)
26186 		return -1;
26187 	}
26188 
26189 #ifdef WIN3264
26190 # if _WIN32_WINNT >= 0x0500
26191 	if (vim_strchr(*fnamep, '~') != NULL)
26192 	{
26193 	    /* Expand 8.3 filename to full path.  Needed to make sure the same
26194 	     * file does not have two different names.
26195 	     * Note: problem does not occur if _WIN32_WINNT < 0x0500. */
26196 	    p = alloc(_MAX_PATH + 1);
26197 	    if (p != NULL)
26198 	    {
26199 		if (GetLongPathName((LPSTR)*fnamep, (LPSTR)p, _MAX_PATH))
26200 		{
26201 		    vim_free(*bufp);
26202 		    *bufp = *fnamep = p;
26203 		}
26204 		else
26205 		    vim_free(p);
26206 	    }
26207 	}
26208 # endif
26209 #endif
26210 	/* Append a path separator to a directory. */
26211 	if (mch_isdir(*fnamep))
26212 	{
26213 	    /* Make room for one or two extra characters. */
26214 	    *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2);
26215 	    vim_free(*bufp);	/* free any allocated file name */
26216 	    *bufp = *fnamep;
26217 	    if (*fnamep == NULL)
26218 		return -1;
26219 	    add_pathsep(*fnamep);
26220 	}
26221     }
26222 
26223     /* ":." - path relative to the current directory */
26224     /* ":~" - path relative to the home directory */
26225     /* ":8" - shortname path - postponed till after */
26226     while (src[*usedlen] == ':'
26227 		  && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8'))
26228     {
26229 	*usedlen += 2;
26230 	if (c == '8')
26231 	{
26232 #ifdef WIN3264
26233 	    has_shortname = 1; /* Postpone this. */
26234 #endif
26235 	    continue;
26236 	}
26237 	pbuf = NULL;
26238 	/* Need full path first (use expand_env() to remove a "~/") */
26239 	if (!has_fullname)
26240 	{
26241 	    if (c == '.' && **fnamep == '~')
26242 		p = pbuf = expand_env_save(*fnamep);
26243 	    else
26244 		p = pbuf = FullName_save(*fnamep, FALSE);
26245 	}
26246 	else
26247 	    p = *fnamep;
26248 
26249 	has_fullname = 0;
26250 
26251 	if (p != NULL)
26252 	{
26253 	    if (c == '.')
26254 	    {
26255 		mch_dirname(dirname, MAXPATHL);
26256 		s = shorten_fname(p, dirname);
26257 		if (s != NULL)
26258 		{
26259 		    *fnamep = s;
26260 		    if (pbuf != NULL)
26261 		    {
26262 			vim_free(*bufp);   /* free any allocated file name */
26263 			*bufp = pbuf;
26264 			pbuf = NULL;
26265 		    }
26266 		}
26267 	    }
26268 	    else
26269 	    {
26270 		home_replace(NULL, p, dirname, MAXPATHL, TRUE);
26271 		/* Only replace it when it starts with '~' */
26272 		if (*dirname == '~')
26273 		{
26274 		    s = vim_strsave(dirname);
26275 		    if (s != NULL)
26276 		    {
26277 			*fnamep = s;
26278 			vim_free(*bufp);
26279 			*bufp = s;
26280 		    }
26281 		}
26282 	    }
26283 	    vim_free(pbuf);
26284 	}
26285     }
26286 
26287     tail = gettail(*fnamep);
26288     *fnamelen = (int)STRLEN(*fnamep);
26289 
26290     /* ":h" - head, remove "/file_name", can be repeated  */
26291     /* Don't remove the first "/" or "c:\" */
26292     while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h')
26293     {
26294 	valid |= VALID_HEAD;
26295 	*usedlen += 2;
26296 	s = get_past_head(*fnamep);
26297 	while (tail > s && after_pathsep(s, tail))
26298 	    mb_ptr_back(*fnamep, tail);
26299 	*fnamelen = (int)(tail - *fnamep);
26300 #ifdef VMS
26301 	if (*fnamelen > 0)
26302 	    *fnamelen += 1; /* the path separator is part of the path */
26303 #endif
26304 	if (*fnamelen == 0)
26305 	{
26306 	    /* Result is empty.  Turn it into "." to make ":cd %:h" work. */
26307 	    p = vim_strsave((char_u *)".");
26308 	    if (p == NULL)
26309 		return -1;
26310 	    vim_free(*bufp);
26311 	    *bufp = *fnamep = tail = p;
26312 	    *fnamelen = 1;
26313 	}
26314 	else
26315 	{
26316 	    while (tail > s && !after_pathsep(s, tail))
26317 		mb_ptr_back(*fnamep, tail);
26318 	}
26319     }
26320 
26321     /* ":8" - shortname  */
26322     if (src[*usedlen] == ':' && src[*usedlen + 1] == '8')
26323     {
26324 	*usedlen += 2;
26325 #ifdef WIN3264
26326 	has_shortname = 1;
26327 #endif
26328     }
26329 
26330 #ifdef WIN3264
26331     /*
26332      * Handle ":8" after we have done 'heads' and before we do 'tails'.
26333      */
26334     if (has_shortname)
26335     {
26336 	/* Copy the string if it is shortened by :h and when it wasn't copied
26337 	 * yet, because we are going to change it in place.  Avoids changing
26338 	 * the buffer name for "%:8". */
26339 	if (*fnamelen < (int)STRLEN(*fnamep) || *fnamep == fname_start)
26340 	{
26341 	    p = vim_strnsave(*fnamep, *fnamelen);
26342 	    if (p == NULL)
26343 		return -1;
26344 	    vim_free(*bufp);
26345 	    *bufp = *fnamep = p;
26346 	}
26347 
26348 	/* Split into two implementations - makes it easier.  First is where
26349 	 * there isn't a full name already, second is where there is. */
26350 	if (!has_fullname && !vim_isAbsName(*fnamep))
26351 	{
26352 	    if (shortpath_for_partial(fnamep, bufp, fnamelen) == FAIL)
26353 		return -1;
26354 	}
26355 	else
26356 	{
26357 	    int		l = *fnamelen;
26358 
26359 	    /* Simple case, already have the full-name.
26360 	     * Nearly always shorter, so try first time. */
26361 	    if (get_short_pathname(fnamep, bufp, &l) == FAIL)
26362 		return -1;
26363 
26364 	    if (l == 0)
26365 	    {
26366 		/* Couldn't find the filename, search the paths. */
26367 		l = *fnamelen;
26368 		if (shortpath_for_invalid_fname(fnamep, bufp, &l) == FAIL)
26369 		    return -1;
26370 	    }
26371 	    *fnamelen = l;
26372 	}
26373     }
26374 #endif /* WIN3264 */
26375 
26376     /* ":t" - tail, just the basename */
26377     if (src[*usedlen] == ':' && src[*usedlen + 1] == 't')
26378     {
26379 	*usedlen += 2;
26380 	*fnamelen -= (int)(tail - *fnamep);
26381 	*fnamep = tail;
26382     }
26383 
26384     /* ":e" - extension, can be repeated */
26385     /* ":r" - root, without extension, can be repeated */
26386     while (src[*usedlen] == ':'
26387 	    && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r'))
26388     {
26389 	/* find a '.' in the tail:
26390 	 * - for second :e: before the current fname
26391 	 * - otherwise: The last '.'
26392 	 */
26393 	if (src[*usedlen + 1] == 'e' && *fnamep > tail)
26394 	    s = *fnamep - 2;
26395 	else
26396 	    s = *fnamep + *fnamelen - 1;
26397 	for ( ; s > tail; --s)
26398 	    if (s[0] == '.')
26399 		break;
26400 	if (src[*usedlen + 1] == 'e')		/* :e */
26401 	{
26402 	    if (s > tail)
26403 	    {
26404 		*fnamelen += (int)(*fnamep - (s + 1));
26405 		*fnamep = s + 1;
26406 #ifdef VMS
26407 		/* cut version from the extension */
26408 		s = *fnamep + *fnamelen - 1;
26409 		for ( ; s > *fnamep; --s)
26410 		    if (s[0] == ';')
26411 			break;
26412 		if (s > *fnamep)
26413 		    *fnamelen = s - *fnamep;
26414 #endif
26415 	    }
26416 	    else if (*fnamep <= tail)
26417 		*fnamelen = 0;
26418 	}
26419 	else				/* :r */
26420 	{
26421 	    if (s > tail)	/* remove one extension */
26422 		*fnamelen = (int)(s - *fnamep);
26423 	}
26424 	*usedlen += 2;
26425     }
26426 
26427     /* ":s?pat?foo?" - substitute */
26428     /* ":gs?pat?foo?" - global substitute */
26429     if (src[*usedlen] == ':'
26430 	    && (src[*usedlen + 1] == 's'
26431 		|| (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's')))
26432     {
26433 	char_u	    *str;
26434 	char_u	    *pat;
26435 	char_u	    *sub;
26436 	int	    sep;
26437 	char_u	    *flags;
26438 	int	    didit = FALSE;
26439 
26440 	flags = (char_u *)"";
26441 	s = src + *usedlen + 2;
26442 	if (src[*usedlen + 1] == 'g')
26443 	{
26444 	    flags = (char_u *)"g";
26445 	    ++s;
26446 	}
26447 
26448 	sep = *s++;
26449 	if (sep)
26450 	{
26451 	    /* find end of pattern */
26452 	    p = vim_strchr(s, sep);
26453 	    if (p != NULL)
26454 	    {
26455 		pat = vim_strnsave(s, (int)(p - s));
26456 		if (pat != NULL)
26457 		{
26458 		    s = p + 1;
26459 		    /* find end of substitution */
26460 		    p = vim_strchr(s, sep);
26461 		    if (p != NULL)
26462 		    {
26463 			sub = vim_strnsave(s, (int)(p - s));
26464 			str = vim_strnsave(*fnamep, *fnamelen);
26465 			if (sub != NULL && str != NULL)
26466 			{
26467 			    *usedlen = (int)(p + 1 - src);
26468 			    s = do_string_sub(str, pat, sub, flags);
26469 			    if (s != NULL)
26470 			    {
26471 				*fnamep = s;
26472 				*fnamelen = (int)STRLEN(s);
26473 				vim_free(*bufp);
26474 				*bufp = s;
26475 				didit = TRUE;
26476 			    }
26477 			}
26478 			vim_free(sub);
26479 			vim_free(str);
26480 		    }
26481 		    vim_free(pat);
26482 		}
26483 	    }
26484 	    /* after using ":s", repeat all the modifiers */
26485 	    if (didit)
26486 		goto repeat;
26487 	}
26488     }
26489 
26490     if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S')
26491     {
26492 	/* vim_strsave_shellescape() needs a NUL terminated string. */
26493 	c = (*fnamep)[*fnamelen];
26494 	if (c != NUL)
26495 	    (*fnamep)[*fnamelen] = NUL;
26496 	p = vim_strsave_shellescape(*fnamep, FALSE, FALSE);
26497 	if (c != NUL)
26498 	    (*fnamep)[*fnamelen] = c;
26499 	if (p == NULL)
26500 	    return -1;
26501 	vim_free(*bufp);
26502 	*bufp = *fnamep = p;
26503 	*fnamelen = (int)STRLEN(p);
26504 	*usedlen += 2;
26505     }
26506 
26507     return valid;
26508 }
26509 
26510 /*
26511  * Perform a substitution on "str" with pattern "pat" and substitute "sub".
26512  * "flags" can be "g" to do a global substitute.
26513  * Returns an allocated string, NULL for error.
26514  */
26515     char_u *
26516 do_string_sub(
26517     char_u	*str,
26518     char_u	*pat,
26519     char_u	*sub,
26520     char_u	*flags)
26521 {
26522     int		sublen;
26523     regmatch_T	regmatch;
26524     int		i;
26525     int		do_all;
26526     char_u	*tail;
26527     char_u	*end;
26528     garray_T	ga;
26529     char_u	*ret;
26530     char_u	*save_cpo;
26531     char_u	*zero_width = NULL;
26532 
26533     /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */
26534     save_cpo = p_cpo;
26535     p_cpo = empty_option;
26536 
26537     ga_init2(&ga, 1, 200);
26538 
26539     do_all = (flags[0] == 'g');
26540 
26541     regmatch.rm_ic = p_ic;
26542     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
26543     if (regmatch.regprog != NULL)
26544     {
26545 	tail = str;
26546 	end = str + STRLEN(str);
26547 	while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
26548 	{
26549 	    /* Skip empty match except for first match. */
26550 	    if (regmatch.startp[0] == regmatch.endp[0])
26551 	    {
26552 		if (zero_width == regmatch.startp[0])
26553 		{
26554 		    /* avoid getting stuck on a match with an empty string */
26555 		    i = MB_PTR2LEN(tail);
26556 		    mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail,
26557 								   (size_t)i);
26558 		    ga.ga_len += i;
26559 		    tail += i;
26560 		    continue;
26561 		}
26562 		zero_width = regmatch.startp[0];
26563 	    }
26564 
26565 	    /*
26566 	     * Get some space for a temporary buffer to do the substitution
26567 	     * into.  It will contain:
26568 	     * - The text up to where the match is.
26569 	     * - The substituted text.
26570 	     * - The text after the match.
26571 	     */
26572 	    sublen = vim_regsub(&regmatch, sub, tail, FALSE, TRUE, FALSE);
26573 	    if (ga_grow(&ga, (int)((end - tail) + sublen -
26574 			    (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
26575 	    {
26576 		ga_clear(&ga);
26577 		break;
26578 	    }
26579 
26580 	    /* copy the text up to where the match is */
26581 	    i = (int)(regmatch.startp[0] - tail);
26582 	    mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
26583 	    /* add the substituted text */
26584 	    (void)vim_regsub(&regmatch, sub, (char_u *)ga.ga_data
26585 					  + ga.ga_len + i, TRUE, TRUE, FALSE);
26586 	    ga.ga_len += i + sublen - 1;
26587 	    tail = regmatch.endp[0];
26588 	    if (*tail == NUL)
26589 		break;
26590 	    if (!do_all)
26591 		break;
26592 	}
26593 
26594 	if (ga.ga_data != NULL)
26595 	    STRCPY((char *)ga.ga_data + ga.ga_len, tail);
26596 
26597 	vim_regfree(regmatch.regprog);
26598     }
26599 
26600     ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
26601     ga_clear(&ga);
26602     if (p_cpo == empty_option)
26603 	p_cpo = save_cpo;
26604     else
26605 	/* Darn, evaluating {sub} expression changed the value. */
26606 	free_string_option(save_cpo);
26607 
26608     return ret;
26609 }
26610 
26611 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */
26612