xref: /vim-8.2.3635/src/eval.c (revision 89cb5e0f)
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 #if defined(MSDOS) || defined(MSWIN)
14 # include <io.h>	/* for mch_open(), must be before vim.h */
15 #endif
16 
17 #include "vim.h"
18 
19 #ifdef AMIGA
20 # include <time.h>	/* for strftime() */
21 #endif
22 
23 #ifdef MACOS
24 # include <time.h>	/* for time_t */
25 #endif
26 
27 #ifdef HAVE_FCNTL_H
28 # include <fcntl.h>
29 #endif
30 
31 #if defined(FEAT_EVAL) || defined(PROTO)
32 
33 #if SIZEOF_INT <= 3		/* use long if int is smaller than 32 bits */
34 typedef long	varnumber_T;
35 #else
36 typedef int	varnumber_T;
37 #endif
38 
39 /*
40  * Structure to hold an internal variable.
41  */
42 typedef struct
43 {
44     char_u	*var_name;	/* name of variable */
45     char	var_type;	/* VAR_NUMBER or VAR_STRING */
46     union
47     {
48 	varnumber_T	var_number;   /* number value */
49 	char_u		*var_string;  /* string value (Careful: can be NULL!) */
50     } var_val;
51 } var;
52 
53 #define VAR_UNKNOWN 0
54 #define VAR_NUMBER  1
55 #define VAR_STRING  2
56 
57 typedef var *	VAR;
58 
59 /*
60  * All user-defined global variables are stored in "variables".
61  */
62 garray_T	variables = {0, 0, sizeof(var), 4, NULL};
63 
64 /*
65  * Array to hold an array with variables local to each sourced script.
66  */
67 static garray_T	    ga_scripts = {0, 0, sizeof(garray_T), 4, NULL};
68 #define SCRIPT_VARS(id) (((garray_T *)ga_scripts.ga_data)[(id) - 1])
69 
70 
71 #define VAR_ENTRY(idx)	(((VAR)(variables.ga_data))[idx])
72 #define VAR_GAP_ENTRY(idx, gap)	(((VAR)(gap->ga_data))[idx])
73 #define BVAR_ENTRY(idx)	(((VAR)(curbuf->b_vars.ga_data))[idx])
74 #define WVAR_ENTRY(idx)	(((VAR)(curwin->w_vars.ga_data))[idx])
75 
76 static int echo_attr = 0;   /* attributes used for ":echo" */
77 
78 /*
79  * Structure to hold info for a user function.
80  */
81 typedef struct ufunc ufunc_T;
82 
83 struct ufunc
84 {
85     ufunc_T	*next;		/* next function in list */
86     char_u	*name;		/* name of function; can start with <SNR>123_
87 				   (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) */
88     int		varargs;	/* variable nr of arguments */
89     int		flags;
90     int		calls;		/* nr of active calls */
91     garray_T	args;		/* arguments */
92     garray_T	lines;		/* function lines */
93     scid_T	script_ID;	/* ID of script where function was defined,
94 				   used for s: variables */
95 };
96 
97 /* function flags */
98 #define FC_ABORT    1		/* abort function on error */
99 #define FC_RANGE    2		/* function accepts range */
100 
101 /*
102  * All user-defined functions are found in the forward-linked function list.
103  * The first function is pointed at by firstfunc.
104  */
105 ufunc_T		*firstfunc = NULL;
106 
107 #define FUNCARG(fp, j)	((char_u **)(fp->args.ga_data))[j]
108 #define FUNCLINE(fp, j)	((char_u **)(fp->lines.ga_data))[j]
109 
110 /* structure to hold info for a function that is currently being executed. */
111 struct funccall
112 {
113     ufunc_T	*func;		/* function being called */
114     int		linenr;		/* next line to be executed */
115     int		returned;	/* ":return" used */
116     int		argcount;	/* nr of arguments */
117     VAR		argvars;	/* arguments */
118     var		a0_var;		/* "a:0" variable */
119     var		firstline;	/* "a:firstline" variable */
120     var		lastline;	/* "a:lastline" variable */
121     garray_T	l_vars;		/* local function variables */
122     VAR		retvar;		/* return value variable */
123     linenr_T	breakpoint;	/* next line with breakpoint or zero */
124     int		dbg_tick;	/* debug_tick when breakpoint was set */
125     int		level;		/* top nesting level of executed function */
126 };
127 
128 /*
129  * Return the name of the executed function.
130  */
131     char_u *
132 func_name(cookie)
133     void *cookie;
134 {
135     return ((struct funccall *)cookie)->func->name;
136 }
137 
138 /*
139  * Return the address holding the next breakpoint line for a funccall cookie.
140  */
141     linenr_T *
142 func_breakpoint(cookie)
143     void *cookie;
144 {
145     return &((struct funccall *)cookie)->breakpoint;
146 }
147 
148 /*
149  * Return the address holding the debug tick for a funccall cookie.
150  */
151     int *
152 func_dbg_tick(cookie)
153     void *cookie;
154 {
155     return &((struct funccall *)cookie)->dbg_tick;
156 }
157 
158 /*
159  * Return the nesting level for a funccall cookie.
160  */
161     int
162 func_level(cookie)
163     void *cookie;
164 {
165     return ((struct funccall *)cookie)->level;
166 }
167 
168 /* pointer to funccal for currently active function */
169 struct funccall *current_funccal = NULL;
170 
171 /*
172  * Return TRUE when a function was ended by a ":return" command.
173  */
174     int
175 current_func_returned()
176 {
177     return current_funccal->returned;
178 }
179 
180 
181 /*
182  * Array to hold the value of v: variables.
183  */
184 #include "version.h"
185 
186 /* values for flags: */
187 #define VV_COMPAT   1	    /* compatible, also used without "v:" */
188 #define VV_RO	    2	    /* read-only */
189 
190 struct vimvar
191 {
192     char	*name;		/* name of variable, without v: */
193     int		len;		/* length of name */
194     char_u	*val;		/* current value (can also be a number!) */
195     char	type;		/* VAR_NUMBER or VAR_STRING */
196     char	flags;		/* VV_COMPAT and VV_RO */
197 } vimvars[VV_LEN] =
198 {   /* The order here must match the VV_ defines in vim.h! */
199     {"count", sizeof("count") - 1, NULL, VAR_NUMBER, VV_COMPAT+VV_RO},
200     {"count1", sizeof("count1") - 1, NULL, VAR_NUMBER, VV_RO},
201     {"prevcount", sizeof("prevcount") - 1, NULL, VAR_NUMBER, VV_RO},
202     {"errmsg", sizeof("errmsg") - 1, NULL, VAR_STRING, VV_COMPAT},
203     {"warningmsg", sizeof("warningmsg") - 1, NULL, VAR_STRING, 0},
204     {"statusmsg", sizeof("statusmsg") - 1, NULL, VAR_STRING, 0},
205     {"shell_error", sizeof("shell_error") - 1, NULL, VAR_NUMBER,
206 							     VV_COMPAT+VV_RO},
207     {"this_session", sizeof("this_session") - 1, NULL, VAR_STRING, VV_COMPAT},
208     {"version", sizeof("version") - 1, (char_u *)VIM_VERSION_100,
209 						 VAR_NUMBER, VV_COMPAT+VV_RO},
210     {"lnum", sizeof("lnum") - 1, NULL, VAR_NUMBER, VV_RO},
211     {"termresponse", sizeof("termresponse") - 1, NULL, VAR_STRING, VV_RO},
212     {"fname", sizeof("fname") - 1, NULL, VAR_STRING, VV_RO},
213     {"lang", sizeof("lang") - 1, NULL, VAR_STRING, VV_RO},
214     {"lc_time", sizeof("lc_time") - 1, NULL, VAR_STRING, VV_RO},
215     {"ctype", sizeof("ctype") - 1, NULL, VAR_STRING, VV_RO},
216     {"charconvert_from", sizeof("charconvert_from") - 1, NULL, VAR_STRING, VV_RO},
217     {"charconvert_to", sizeof("charconvert_to") - 1, NULL, VAR_STRING, VV_RO},
218     {"fname_in", sizeof("fname_in") - 1, NULL, VAR_STRING, VV_RO},
219     {"fname_out", sizeof("fname_out") - 1, NULL, VAR_STRING, VV_RO},
220     {"fname_new", sizeof("fname_new") - 1, NULL, VAR_STRING, VV_RO},
221     {"fname_diff", sizeof("fname_diff") - 1, NULL, VAR_STRING, VV_RO},
222     {"cmdarg", sizeof("cmdarg") - 1, NULL, VAR_STRING, VV_RO},
223     {"foldstart", sizeof("foldstart") - 1, NULL, VAR_NUMBER, VV_RO},
224     {"foldend", sizeof("foldend") - 1, NULL, VAR_NUMBER, VV_RO},
225     {"folddashes", sizeof("folddashes") - 1, NULL, VAR_STRING, VV_RO},
226     {"foldlevel", sizeof("foldlevel") - 1, NULL, VAR_NUMBER, VV_RO},
227     {"progname", sizeof("progname") - 1, NULL, VAR_STRING, VV_RO},
228     {"servername", sizeof("servername") - 1, NULL, VAR_STRING, VV_RO},
229     {"dying", sizeof("dying") - 1, NULL, VAR_NUMBER, VV_RO},
230     {"exception", sizeof("exception") - 1, NULL, VAR_STRING, VV_RO},
231     {"throwpoint", sizeof("throwpoint") - 1, NULL, VAR_STRING, VV_RO},
232     {"register", sizeof("register") - 1, NULL, VAR_STRING, VV_RO},
233     {"cmdbang", sizeof("cmdbang") - 1, NULL, VAR_NUMBER, VV_RO},
234     {"insertmode", sizeof("insertmode") - 1, NULL, VAR_STRING, VV_RO},
235 };
236 
237 static int eval0 __ARGS((char_u *arg,  VAR retvar, char_u **nextcmd, int evaluate));
238 static int eval1 __ARGS((char_u **arg, VAR retvar, int evaluate));
239 static int eval2 __ARGS((char_u **arg, VAR retvar, int evaluate));
240 static int eval3 __ARGS((char_u **arg, VAR retvar, int evaluate));
241 static int eval4 __ARGS((char_u **arg, VAR retvar, int evaluate));
242 static int eval5 __ARGS((char_u **arg, VAR retvar, int evaluate));
243 static int eval6 __ARGS((char_u **arg, VAR retvar, int evaluate));
244 static int eval7 __ARGS((char_u **arg, VAR retvar, int evaluate));
245 static int get_option_var __ARGS((char_u **arg, VAR retvar, int evaluate));
246 static int get_string_var __ARGS((char_u **arg, VAR retvar, int evaluate));
247 static int get_lit_string_var __ARGS((char_u **arg, VAR retvar, int evaluate));
248 static int get_env_var __ARGS((char_u **arg, VAR retvar, int evaluate));
249 static int find_internal_func __ARGS((char_u *name));
250 static int get_func_var __ARGS((char_u *name, int len, VAR retvar, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate));
251 static int call_func __ARGS((char_u *name, int len, VAR retvar, int argcount, VAR argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate));
252 static void f_append __ARGS((VAR argvars, VAR retvar));
253 static void f_argc __ARGS((VAR argvars, VAR retvar));
254 static void f_argidx __ARGS((VAR argvars, VAR retvar));
255 static void f_argv __ARGS((VAR argvars, VAR retvar));
256 static void f_browse __ARGS((VAR argvars, VAR retvar));
257 static buf_T *find_buffer __ARGS((VAR avar));
258 static void f_bufexists __ARGS((VAR argvars, VAR retvar));
259 static void f_buflisted __ARGS((VAR argvars, VAR retvar));
260 static void f_bufloaded __ARGS((VAR argvars, VAR retvar));
261 static buf_T *get_buf_var __ARGS((VAR avar));
262 static void f_bufname __ARGS((VAR argvars, VAR retvar));
263 static void f_bufnr __ARGS((VAR argvars, VAR retvar));
264 static void f_bufwinnr __ARGS((VAR argvars, VAR retvar));
265 static void f_byte2line __ARGS((VAR argvars, VAR retvar));
266 static void f_byteidx __ARGS((VAR argvars, VAR retvar));
267 static void f_char2nr __ARGS((VAR argvars, VAR retvar));
268 static void f_cindent __ARGS((VAR argvars, VAR retvar));
269 static void f_col __ARGS((VAR argvars, VAR retvar));
270 static void f_confirm __ARGS((VAR argvars, VAR retvar));
271 static void f_cscope_connection __ARGS((VAR argvars, VAR retvar));
272 static void f_cursor __ARGS((VAR argsvars, VAR retvar));
273 static void f_delete __ARGS((VAR argvars, VAR retvar));
274 static void f_did_filetype __ARGS((VAR argvars, VAR retvar));
275 static void f_escape __ARGS((VAR argvars, VAR retvar));
276 static void f_eventhandler __ARGS((VAR argvars, VAR retvar));
277 static void f_executable __ARGS((VAR argvars, VAR retvar));
278 static void f_exists __ARGS((VAR argvars, VAR retvar));
279 static void f_expand __ARGS((VAR argvars, VAR retvar));
280 static void f_filereadable __ARGS((VAR argvars, VAR retvar));
281 static void f_filewritable __ARGS((VAR argvars, VAR retvar));
282 static void f_finddir __ARGS((VAR argvars, VAR retvar));
283 static void f_findfile __ARGS((VAR argvars, VAR retvar));
284 static void f_findfilendir __ARGS((VAR argvars, VAR retvar, int dir));
285 static void f_fnamemodify __ARGS((VAR argvars, VAR retvar));
286 static void f_foldclosed __ARGS((VAR argvars, VAR retvar));
287 static void f_foldclosedend __ARGS((VAR argvars, VAR retvar));
288 static void foldclosed_both __ARGS((VAR argvars, VAR retvar, int end));
289 static void f_foldlevel __ARGS((VAR argvars, VAR retvar));
290 static void f_foldtext __ARGS((VAR argvars, VAR retvar));
291 static void f_foreground __ARGS((VAR argvars, VAR retvar));
292 static void f_getbufvar __ARGS((VAR argvars, VAR retvar));
293 static void f_getchar __ARGS((VAR argvars, VAR retvar));
294 static void f_getcharmod __ARGS((VAR argvars, VAR retvar));
295 static void f_getcmdline __ARGS((VAR argvars, VAR retvar));
296 static void f_getcmdpos __ARGS((VAR argvars, VAR retvar));
297 static void f_getcwd __ARGS((VAR argvars, VAR retvar));
298 static void f_getfsize __ARGS((VAR argvars, VAR retvar));
299 static void f_getftime __ARGS((VAR argvars, VAR retvar));
300 static void f_getline __ARGS((VAR argvars, VAR retvar));
301 static void f_getreg __ARGS((VAR argvars, VAR retvar));
302 static void f_getregtype __ARGS((VAR argvars, VAR retvar));
303 static void f_getwinposx __ARGS((VAR argvars, VAR retvar));
304 static void f_getwinposy __ARGS((VAR argvars, VAR retvar));
305 static void f_getwinvar __ARGS((VAR argvars, VAR retvar));
306 static void f_glob __ARGS((VAR argvars, VAR retvar));
307 static void f_globpath __ARGS((VAR argvars, VAR retvar));
308 static void f_has __ARGS((VAR argvars, VAR retvar));
309 static void f_hasmapto __ARGS((VAR argvars, VAR retvar));
310 static void f_histadd __ARGS((VAR argvars, VAR retvar));
311 static void f_histdel __ARGS((VAR argvars, VAR retvar));
312 static void f_histget __ARGS((VAR argvars, VAR retvar));
313 static void f_histnr __ARGS((VAR argvars, VAR retvar));
314 static void f_hlexists __ARGS((VAR argvars, VAR retvar));
315 static void f_hlID __ARGS((VAR argvars, VAR retvar));
316 static void f_hostname __ARGS((VAR argvars, VAR retvar));
317 static void f_iconv __ARGS((VAR argvars, VAR retvar));
318 static void f_indent __ARGS((VAR argvars, VAR retvar));
319 static void f_isdirectory __ARGS((VAR argvars, VAR retvar));
320 static void f_input __ARGS((VAR argvars, VAR retvar));
321 static void f_inputdialog __ARGS((VAR argvars, VAR retvar));
322 static void f_inputrestore __ARGS((VAR argvars, VAR retvar));
323 static void f_inputsave __ARGS((VAR argvars, VAR retvar));
324 static void f_inputsecret __ARGS((VAR argvars, VAR retvar));
325 static void f_last_buffer_nr __ARGS((VAR argvars, VAR retvar));
326 static void f_libcall __ARGS((VAR argvars, VAR retvar));
327 static void f_libcallnr __ARGS((VAR argvars, VAR retvar));
328 static void libcall_common __ARGS((VAR argvars, VAR retvar, int type));
329 static void f_line __ARGS((VAR argvars, VAR retvar));
330 static void f_line2byte __ARGS((VAR argvars, VAR retvar));
331 static void f_lispindent __ARGS((VAR argvars, VAR retvar));
332 static void f_localtime __ARGS((VAR argvars, VAR retvar));
333 static void f_maparg __ARGS((VAR argvars, VAR retvar));
334 static void f_mapcheck __ARGS((VAR argvars, VAR retvar));
335 static void get_maparg __ARGS((VAR argvars, VAR retvar, int exact));
336 static void f_match __ARGS((VAR argvars, VAR retvar));
337 static void f_matchend __ARGS((VAR argvars, VAR retvar));
338 static void f_matchstr __ARGS((VAR argvars, VAR retvar));
339 static void f_mode __ARGS((VAR argvars, VAR retvar));
340 static void f_nextnonblank __ARGS((VAR argvars, VAR retvar));
341 static void f_nr2char __ARGS((VAR argvars, VAR retvar));
342 static void f_prevnonblank __ARGS((VAR argvars, VAR retvar));
343 static void f_setbufvar __ARGS((VAR argvars, VAR retvar));
344 static void f_setcmdpos __ARGS((VAR argvars, VAR retvar));
345 static void f_setwinvar __ARGS((VAR argvars, VAR retvar));
346 static void f_rename __ARGS((VAR argvars, VAR retvar));
347 static void f_resolve __ARGS((VAR argvars, VAR retvar));
348 static void f_search __ARGS((VAR argvars, VAR retvar));
349 static void f_searchpair __ARGS((VAR argvars, VAR retvar));
350 static int get_search_arg __ARGS((VAR varp, int *flagsp));
351 static void f_remote_expr __ARGS((VAR argvars, VAR retvar));
352 static void f_remote_foreground __ARGS((VAR argvars, VAR retvar));
353 static void f_remote_peek __ARGS((VAR argvars, VAR retvar));
354 static void f_remote_read __ARGS((VAR argvars, VAR retvar));
355 static void f_remote_send __ARGS((VAR argvars, VAR retvar));
356 static void f_repeat __ARGS((VAR argvars, VAR retvar));
357 static void f_server2client __ARGS((VAR argvars, VAR retvar));
358 static void f_serverlist __ARGS((VAR argvars, VAR retvar));
359 static void f_setline __ARGS((VAR argvars, VAR retvar));
360 static void f_setreg __ARGS((VAR argvars, VAR retvar));
361 static void f_simplify __ARGS((VAR argvars, VAR retvar));
362 static void find_some_match __ARGS((VAR argvars, VAR retvar, int start));
363 static void f_strftime __ARGS((VAR argvars, VAR retvar));
364 static void f_stridx __ARGS((VAR argvars, VAR retvar));
365 static void f_strlen __ARGS((VAR argvars, VAR retvar));
366 static void f_strpart __ARGS((VAR argvars, VAR retvar));
367 static void f_strridx __ARGS((VAR argvars, VAR retvar));
368 static void f_strtrans __ARGS((VAR argvars, VAR retvar));
369 static void f_synID __ARGS((VAR argvars, VAR retvar));
370 static void f_synIDattr __ARGS((VAR argvars, VAR retvar));
371 static void f_synIDtrans __ARGS((VAR argvars, VAR retvar));
372 static void f_system __ARGS((VAR argvars, VAR retvar));
373 static void f_submatch __ARGS((VAR argvars, VAR retvar));
374 static void f_substitute __ARGS((VAR argvars, VAR retvar));
375 static void f_tempname __ARGS((VAR argvars, VAR retvar));
376 static void f_tolower __ARGS((VAR argvars, VAR retvar));
377 static void f_toupper __ARGS((VAR argvars, VAR retvar));
378 static void f_tr __ARGS((VAR argvars, VAR retvar));
379 static void f_type __ARGS((VAR argvars, VAR retvar));
380 static void f_virtcol __ARGS((VAR argvars, VAR retvar));
381 static void f_visualmode __ARGS((VAR argvars, VAR retvar));
382 static void f_winbufnr __ARGS((VAR argvars, VAR retvar));
383 static void f_wincol __ARGS((VAR argvars, VAR retvar));
384 static void f_winheight __ARGS((VAR argvars, VAR retvar));
385 static void f_winline __ARGS((VAR argvars, VAR retvar));
386 static void f_winnr __ARGS((VAR argvars, VAR retvar));
387 static void f_winrestcmd __ARGS((VAR argvars, VAR retvar));
388 static void f_winwidth __ARGS((VAR argvars, VAR retvar));
389 static win_T *find_win_by_nr __ARGS((VAR vp));
390 static pos_T *var2fpos __ARGS((VAR varp, int lnum));
391 static int get_env_len __ARGS((char_u **arg));
392 static int get_id_len __ARGS((char_u **arg));
393 static int get_func_len __ARGS((char_u **arg, char_u **alias, int evaluate));
394 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end));
395 static int eval_isnamec __ARGS((int c));
396 static int find_vim_var __ARGS((char_u *name, int len));
397 static int get_var_var __ARGS((char_u *name, int len, VAR retvar));
398 static VAR alloc_var __ARGS((void));
399 static VAR alloc_string_var __ARGS((char_u *string));
400 static void free_var __ARGS((VAR varp));
401 static void clear_var __ARGS((VAR varp));
402 static long get_var_number __ARGS((VAR varp));
403 static linenr_T get_var_lnum __ARGS((VAR argvars));
404 static char_u *get_var_string __ARGS((VAR varp));
405 static char_u *get_var_string_buf __ARGS((VAR varp, char_u *buf));
406 static VAR find_var __ARGS((char_u *name, int writing));
407 static VAR find_var_in_ga __ARGS((garray_T *gap, char_u *varname));
408 static garray_T *find_var_ga __ARGS((char_u *name, char_u **varname));
409 static void var_free_one __ARGS((VAR v));
410 static void list_one_var __ARGS((VAR v, char_u *prefix));
411 static void list_vim_var __ARGS((int i));
412 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string));
413 static void set_var __ARGS((char_u *name, VAR varp));
414 static void copy_var __ARGS((VAR from, VAR to));
415 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags));
416 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int internal));
417 static int eval_fname_script __ARGS((char_u *p));
418 static int eval_fname_sid __ARGS((char_u *p));
419 static void list_func_head __ARGS((ufunc_T *fp, int indent));
420 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
421 static ufunc_T *find_func __ARGS((char_u *name));
422 static void call_user_func __ARGS((ufunc_T *fp, int argcount, VAR argvars, VAR retvar, linenr_T firstline, linenr_T lastline));
423 
424 /* Magic braces are always enabled, otherwise Vim scripts would not be
425  * portable. */
426 #define FEAT_MAGIC_BRACES
427 
428 #ifdef FEAT_MAGIC_BRACES
429 static char_u * make_expanded_name __ARGS((char_u *in_start,  char_u *expr_start,  char_u *expr_end,  char_u *in_end));
430 #endif
431 
432 /*
433  * Set an internal variable to a string value. Creates the variable if it does
434  * not already exist.
435  */
436     void
437 set_internal_string_var(name, value)
438     char_u	*name;
439     char_u	*value;
440 {
441     char_u  *val;
442     VAR	    varp;
443 
444     val = vim_strsave(value);
445     if (val != NULL)
446     {
447 	varp = alloc_string_var(val);
448 	if (varp != NULL)
449 	{
450 	    set_var(name, varp);
451 	    free_var(varp);
452 	}
453     }
454 }
455 
456 # if defined(FEAT_MBYTE) || defined(PROTO)
457     int
458 eval_charconvert(enc_from, enc_to, fname_from, fname_to)
459     char_u	*enc_from;
460     char_u	*enc_to;
461     char_u	*fname_from;
462     char_u	*fname_to;
463 {
464     int		err = FALSE;
465 
466     set_vim_var_string(VV_CC_FROM, enc_from, -1);
467     set_vim_var_string(VV_CC_TO, enc_to, -1);
468     set_vim_var_string(VV_FNAME_IN, fname_from, -1);
469     set_vim_var_string(VV_FNAME_OUT, fname_to, -1);
470     if (eval_to_bool(p_ccv, &err, NULL, FALSE))
471 	err = TRUE;
472     set_vim_var_string(VV_CC_FROM, NULL, -1);
473     set_vim_var_string(VV_CC_TO, NULL, -1);
474     set_vim_var_string(VV_FNAME_IN, NULL, -1);
475     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
476 
477     if (err)
478 	return FAIL;
479     return OK;
480 }
481 # endif
482 
483 # if defined(FEAT_POSTSCRIPT) || defined(PROTO)
484     int
485 eval_printexpr(fname, args)
486     char_u	*fname;
487     char_u	*args;
488 {
489     int		err = FALSE;
490 
491     set_vim_var_string(VV_FNAME_IN, fname, -1);
492     set_vim_var_string(VV_CMDARG, args, -1);
493     if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
494 	err = TRUE;
495     set_vim_var_string(VV_FNAME_IN, NULL, -1);
496     set_vim_var_string(VV_CMDARG, NULL, -1);
497 
498     if (err)
499     {
500 	mch_remove(fname);
501 	return FAIL;
502     }
503     return OK;
504 }
505 # endif
506 
507 # if defined(FEAT_DIFF) || defined(PROTO)
508     void
509 eval_diff(origfile, newfile, outfile)
510     char_u	*origfile;
511     char_u	*newfile;
512     char_u	*outfile;
513 {
514     int		err = FALSE;
515 
516     set_vim_var_string(VV_FNAME_IN, origfile, -1);
517     set_vim_var_string(VV_FNAME_NEW, newfile, -1);
518     set_vim_var_string(VV_FNAME_OUT, outfile, -1);
519     (void)eval_to_bool(p_dex, &err, NULL, FALSE);
520     set_vim_var_string(VV_FNAME_IN, NULL, -1);
521     set_vim_var_string(VV_FNAME_NEW, NULL, -1);
522     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
523 }
524 
525     void
526 eval_patch(origfile, difffile, outfile)
527     char_u	*origfile;
528     char_u	*difffile;
529     char_u	*outfile;
530 {
531     int		err;
532 
533     set_vim_var_string(VV_FNAME_IN, origfile, -1);
534     set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
535     set_vim_var_string(VV_FNAME_OUT, outfile, -1);
536     (void)eval_to_bool(p_pex, &err, NULL, FALSE);
537     set_vim_var_string(VV_FNAME_IN, NULL, -1);
538     set_vim_var_string(VV_FNAME_DIFF, NULL, -1);
539     set_vim_var_string(VV_FNAME_OUT, NULL, -1);
540 }
541 # endif
542 
543 /*
544  * Top level evaluation function, returning a boolean.
545  * Sets "error" to TRUE if there was an error.
546  * Return TRUE or FALSE.
547  */
548     int
549 eval_to_bool(arg, error, nextcmd, skip)
550     char_u	*arg;
551     int		*error;
552     char_u	**nextcmd;
553     int		skip;	    /* only parse, don't execute */
554 {
555     var		retvar;
556     int		retval = FALSE;
557 
558     if (skip)
559 	++emsg_skip;
560     if (eval0(arg, &retvar, nextcmd, !skip) == FAIL)
561     {
562 	*error = TRUE;
563     }
564     else
565     {
566 	*error = FALSE;
567 	if (!skip)
568 	{
569 	    retval = (get_var_number(&retvar) != 0);
570 	    clear_var(&retvar);
571 	}
572     }
573     if (skip)
574 	--emsg_skip;
575 
576     return retval;
577 }
578 
579 /*
580  * Top level evaluation function, returning a string.  If "skip" is TRUE,
581  * only parsing to "nextcmd" is done, without reporting errors.  Return
582  * pointer to allocated memory, or NULL for failure or when "skip" is TRUE.
583  */
584     char_u *
585 eval_to_string_skip(arg, nextcmd, skip)
586     char_u	*arg;
587     char_u	**nextcmd;
588     int		skip;	    /* only parse, don't execute */
589 {
590     var		retvar;
591     char_u	*retval;
592 
593     if (skip)
594 	++emsg_skip;
595     if (eval0(arg, &retvar, nextcmd, !skip) == FAIL || skip)
596 	retval = NULL;
597     else
598     {
599 	retval = vim_strsave(get_var_string(&retvar));
600 	clear_var(&retvar);
601     }
602     if (skip)
603 	--emsg_skip;
604 
605     return retval;
606 }
607 
608 /*
609  * Skip over an expression at "*pp".
610  * Return FAIL for an error, OK otherwise.
611  */
612     int
613 skip_expr(pp)
614     char_u	**pp;
615 {
616     var		retvar;
617 
618     *pp = skipwhite(*pp);
619     return eval1(pp, &retvar, FALSE);
620 }
621 
622 /*
623  * Top level evaluation function, returning a string.
624  * Return pointer to allocated memory, or NULL for failure.
625  */
626     char_u *
627 eval_to_string(arg, nextcmd)
628     char_u	*arg;
629     char_u	**nextcmd;
630 {
631     var		retvar;
632     char_u	*retval;
633 
634     if (eval0(arg, &retvar, nextcmd, TRUE) == FAIL)
635 	retval = NULL;
636     else
637     {
638 	retval = vim_strsave(get_var_string(&retvar));
639 	clear_var(&retvar);
640     }
641 
642     return retval;
643 }
644 
645 /*
646  * Call eval_to_string() with "sandbox" set and not using local variables.
647  */
648     char_u *
649 eval_to_string_safe(arg, nextcmd)
650     char_u	*arg;
651     char_u	**nextcmd;
652 {
653     char_u	*retval;
654     void	*save_funccalp;
655 
656     save_funccalp = save_funccal();
657     ++sandbox;
658     retval = eval_to_string(arg, nextcmd);
659     --sandbox;
660     restore_funccal(save_funccalp);
661     return retval;
662 }
663 
664 #if 0 /* not used */
665 /*
666  * Top level evaluation function, returning a string.
667  * Advances "arg" to the first non-blank after the evaluated expression.
668  * Return pointer to allocated memory, or NULL for failure.
669  * Doesn't give error messages.
670  */
671     char_u *
672 eval_arg_to_string(arg)
673     char_u	**arg;
674 {
675     var		retvar;
676     char_u	*retval;
677     int		ret;
678 
679     ++emsg_off;
680 
681     ret = eval1(arg, &retvar, TRUE);
682     if (ret == FAIL)
683 	retval = NULL;
684     else
685     {
686 	retval = vim_strsave(get_var_string(&retvar));
687 	clear_var(&retvar);
688     }
689 
690     --emsg_off;
691 
692     return retval;
693 }
694 #endif
695 
696 /*
697  * Top level evaluation function, returning a number.
698  * Evaluates "expr" silently.
699  * Returns -1 for an error.
700  */
701     int
702 eval_to_number(expr)
703     char_u	*expr;
704 {
705     var		retvar;
706     int		retval;
707     char_u	*p = expr;
708 
709     ++emsg_off;
710 
711     if (eval1(&p, &retvar, TRUE) == FAIL)
712 	retval = -1;
713     else
714     {
715 	retval = get_var_number(&retvar);
716 	clear_var(&retvar);
717     }
718     --emsg_off;
719 
720     return retval;
721 }
722 
723 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
724 /*
725  * Call some vimL function and return the result as a string
726  * Uses argv[argc] for the function arguments.
727  */
728     char_u *
729 call_vim_function(func, argc, argv, safe)
730     char_u      *func;
731     int		argc;
732     char_u      **argv;
733     int		safe;		/* use the sandbox */
734 {
735     char_u	*retval = NULL;
736     var		retvar;
737     VAR		argvars;
738     long	n;
739     int		len;
740     int		i;
741     int		doesrange;
742     void	*save_funccalp = NULL;
743 
744     argvars = (VAR)alloc((unsigned)(argc * sizeof(var)));
745     if (argvars == NULL)
746 	return NULL;
747 
748     for (i = 0; i < argc; i++)
749     {
750 	/* Pass a NULL or empty argument as an empty string */
751 	if (argv[i] == NULL || *argv[i] == NUL)
752 	{
753 	    argvars[i].var_type = VAR_STRING;
754 	    argvars[i].var_val.var_string = "";
755 	    continue;
756 	}
757 
758 	/* Recognize a number argument, the others must be strings. */
759 	vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL);
760 	if (len != 0 && len == (int)STRLEN(argv[i]))
761 	{
762 	    argvars[i].var_type = VAR_NUMBER;
763 	    argvars[i].var_val.var_number = n;
764 	}
765 	else
766 	{
767 	    argvars[i].var_type = VAR_STRING;
768 	    argvars[i].var_val.var_string = argv[i];
769 	}
770     }
771 
772     if (safe)
773     {
774 	save_funccalp = save_funccal();
775 	++sandbox;
776     }
777 
778     retvar.var_type = VAR_UNKNOWN;	/* clear_var() uses this */
779     if (call_func(func, (int)STRLEN(func), &retvar, argc, argvars,
780 		    curwin->w_cursor.lnum, curwin->w_cursor.lnum,
781 		    &doesrange, TRUE) == OK)
782 	retval = vim_strsave(get_var_string(&retvar));
783 
784     clear_var(&retvar);
785     vim_free(argvars);
786 
787     if (safe)
788     {
789 	--sandbox;
790 	restore_funccal(save_funccalp);
791     }
792     return retval;
793 }
794 #endif
795 
796 /*
797  * Save the current function call pointer, and set it to NULL.
798  * Used when executing autocommands and for ":source".
799  */
800     void *
801 save_funccal()
802 {
803     struct funccall *fc;
804 
805     fc = current_funccal;
806     current_funccal = NULL;
807     return (void *)fc;
808 }
809 
810     void
811 restore_funccal(fc)
812     void *fc;
813 {
814     current_funccal = (struct funccall *)fc;
815 }
816 
817 #ifdef FEAT_FOLDING
818 /*
819  * Evaluate 'foldexpr'.  Returns the foldlevel, and any character preceding
820  * it in "*cp".  Doesn't give error messages.
821  */
822     int
823 eval_foldexpr(arg, cp)
824     char_u	*arg;
825     int		*cp;
826 {
827     var		retvar;
828     int		retval;
829     char_u	*s;
830 
831     ++emsg_off;
832     ++sandbox;
833     *cp = NUL;
834     if (eval0(arg, &retvar, NULL, TRUE) == FAIL)
835 	retval = 0;
836     else
837     {
838 	/* If the result is a number, just return the number. */
839 	if (retvar.var_type == VAR_NUMBER)
840 	    retval = retvar.var_val.var_number;
841 	else if (retvar.var_type == VAR_UNKNOWN
842 		|| retvar.var_val.var_string == NULL)
843 	    retval = 0;
844 	else
845 	{
846 	    /* If the result is a string, check if there is a non-digit before
847 	     * the number. */
848 	    s = retvar.var_val.var_string;
849 	    if (!VIM_ISDIGIT(*s) && *s != '-')
850 		*cp = *s++;
851 	    retval = atol((char *)s);
852 	}
853 	clear_var(&retvar);
854     }
855     --emsg_off;
856     --sandbox;
857 
858     return retval;
859 }
860 #endif
861 
862 #ifdef FEAT_MAGIC_BRACES
863 /*
864  * Expands out the 'magic' {}'s in a variable/function name.
865  * Note that this can call itself recursively, to deal with
866  * constructs like foo{bar}{baz}{bam}
867  * The four pointer arguments point to "foo{expre}ss{ion}bar"
868  *			"in_start"      ^
869  *			"expr_start"	   ^
870  *			"expr_end"		 ^
871  *			"in_end"			    ^
872  *
873  * Returns a new allocated string, which the caller must free.
874  * Returns NULL for failure.
875  */
876     static char_u *
877 make_expanded_name(in_start, expr_start, expr_end, in_end)
878     char_u	*in_start;
879     char_u	*expr_start;
880     char_u	*expr_end;
881     char_u	*in_end;
882 {
883     char_u	c1;
884     char_u	*retval = NULL;
885     char_u	*temp_result;
886     char_u	*nextcmd = NULL;
887 
888     if (expr_end == NULL || in_end == NULL)
889 	return NULL;
890     *expr_start	= NUL;
891     *expr_end = NUL;
892     c1 = *in_end;
893     *in_end = NUL;
894 
895     temp_result = eval_to_string(expr_start + 1, &nextcmd);
896     if (temp_result != NULL && nextcmd == NULL)
897     {
898 	retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start)
899 						   + (in_end - expr_end) + 1));
900 
901 	if (retval != NULL)
902 	{
903 	    STRCPY(retval, in_start);
904 	    STRCAT(retval, temp_result);
905 	    STRCAT(retval, expr_end + 1);
906 	}
907     }
908     vim_free(temp_result);
909 
910     *in_end = c1;		/* put char back for error messages */
911     *expr_start = '{';
912     *expr_end = '}';
913 
914     if (retval != NULL)
915     {
916 	temp_result = find_name_end(retval, &expr_start, &expr_end);
917 	if (expr_start != NULL)
918 	{
919 	    /* Further expansion! */
920 	    temp_result = make_expanded_name(retval, expr_start,
921 						       expr_end, temp_result);
922 	    vim_free(retval);
923 	    retval = temp_result;
924 	}
925     }
926 
927     return retval;
928 
929 }
930 #endif /* FEAT_MAGIC_BRACES */
931 
932 /*
933  * ":let var = expr"	assignment command.
934  * ":let var"		list one variable value
935  * ":let"		list all variable values
936  */
937     void
938 ex_let(eap)
939     exarg_T	*eap;
940 {
941     char_u	*arg = eap->arg;
942     char_u	*expr;
943     char_u	*name;
944     VAR		varp;
945     var		retvar;
946     char_u	*p;
947     int		c1 = 0, c2;
948     int		i;
949     char_u	*expr_start;
950     char_u	*expr_end;
951     char_u	*name_end;
952 
953     name_end = find_name_end(arg, &expr_start, &expr_end);
954     expr = vim_strchr(name_end, '=');
955     if (expr == NULL)
956     {
957 	if (ends_excmd(*arg))
958 	{
959 	    if (!eap->skip)
960 	    {
961 		/*
962 		 * List all variables.
963 		 */
964 		for (i = 0; i < variables.ga_len && !got_int; ++i)
965 		    if (VAR_ENTRY(i).var_name != NULL)
966 			list_one_var(&VAR_ENTRY(i), (char_u *)"");
967 		for (i = 0; i < curbuf->b_vars.ga_len && !got_int; ++i)
968 		    if (BVAR_ENTRY(i).var_name != NULL)
969 			list_one_var(&BVAR_ENTRY(i), (char_u *)"b:");
970 		for (i = 0; i < curwin->w_vars.ga_len && !got_int; ++i)
971 		    if (WVAR_ENTRY(i).var_name != NULL)
972 			list_one_var(&WVAR_ENTRY(i), (char_u *)"w:");
973 		for (i = 0; i < VV_LEN && !got_int; ++i)
974 		    if (vimvars[i].type == VAR_NUMBER || vimvars[i].val != NULL)
975 			list_vim_var(i);
976 	    }
977 	}
978 	else
979 	{
980 	    int		error = FALSE;
981 
982 	    /*
983 	     * List variables.
984 	     */
985 	    while (!ends_excmd(*arg) && !got_int)
986 	    {
987 		char_u	*temp_string = NULL;
988 		int	arg_len;
989 
990 		/* Find the end of the name. */
991 		name_end = find_name_end(arg, &expr_start, &expr_end);
992 
993 		if (!vim_iswhite(*name_end) && !ends_excmd(*name_end))
994 		{
995 		    emsg_severe = TRUE;
996 		    EMSG(_(e_trailing));
997 		    break;
998 		}
999 		if (!error && !eap->skip)
1000 		{
1001 #ifdef FEAT_MAGIC_BRACES
1002 		    if (expr_start != NULL)
1003 		    {
1004 			temp_string = make_expanded_name(arg, expr_start,
1005 							 expr_end, name_end);
1006 			if (temp_string == NULL)
1007 			{
1008 			    /*
1009 			     * Report an invalid expression in braces, unless
1010 			     * the expression evaluation has been cancelled due
1011 			     * to an aborting error, an interrupt, or an
1012 			     * exception.
1013 			     */
1014 			    if (!aborting())
1015 			    {
1016 				emsg_severe = TRUE;
1017 				EMSG2(_(e_invarg2), arg);
1018 				break;
1019 			    }
1020 			    error = TRUE;
1021 			    arg = skipwhite(name_end);
1022 			    continue;
1023 			}
1024 			arg = temp_string;
1025 			arg_len = STRLEN(temp_string);
1026 		    }
1027 		    else
1028 #endif
1029 		    {
1030 			c1 = *name_end;
1031 			*name_end = NUL;
1032 			arg_len = (int)(name_end - arg);
1033 		    }
1034 		    i = find_vim_var(arg, arg_len);
1035 		    if (i >= 0)
1036 			list_vim_var(i);
1037 		    else if (STRCMP("b:changedtick", arg) == 0)
1038 		    {
1039 			char_u	numbuf[NUMBUFLEN];
1040 
1041 			sprintf((char *)numbuf, "%ld",
1042 						 (long)curbuf->b_changedtick);
1043 			list_one_var_a((char_u *)"b:", (char_u *)"changedtick",
1044 							  VAR_NUMBER, numbuf);
1045 		    }
1046 		    else
1047 		    {
1048 			varp = find_var(arg, FALSE);
1049 			if (varp == NULL)
1050 			{
1051 			    /* Skip further arguments but do continue to
1052 			     * search for a trailing command. */
1053 			    EMSG2(_("E106: Unknown variable: \"%s\""), arg);
1054 			    error = TRUE;
1055 			}
1056 			else
1057 			{
1058 			    name = vim_strchr(arg, ':');
1059 			    if (name != NULL)
1060 			    {
1061 				/* "a:" vars have no name stored, use whole
1062 				 * arg */
1063 				if (arg[0] == 'a' && arg[1] == ':')
1064 				    c2 = NUL;
1065 				else
1066 				{
1067 				    c2 = *++name;
1068 				    *name = NUL;
1069 				}
1070 				list_one_var(varp, arg);
1071 				if (c2 != NUL)
1072 				    *name = c2;
1073 			    }
1074 			    else
1075 				list_one_var(varp, (char_u *)"");
1076 			}
1077 		    }
1078 #ifdef FEAT_MAGIC_BRACES
1079 		    if (expr_start != NULL)
1080 			vim_free(temp_string);
1081 		    else
1082 #endif
1083 			*name_end = c1;
1084 		}
1085 		arg = skipwhite(name_end);
1086 	    }
1087 	}
1088 	eap->nextcmd = check_nextcmd(arg);
1089     }
1090     else
1091     {
1092 	if (eap->skip)
1093 	    ++emsg_skip;
1094 	i = eval0(expr + 1, &retvar, &eap->nextcmd, !eap->skip);
1095 	if (eap->skip)
1096 	{
1097 	    if (i != FAIL)
1098 		clear_var(&retvar);
1099 	    --emsg_skip;
1100 	}
1101 	else if (i != FAIL)
1102 	{
1103 	    /*
1104 	     * ":let $VAR = expr": Set environment variable.
1105 	     */
1106 	    if (*arg == '$')
1107 	    {
1108 		int	len;
1109 		int	cc;
1110 
1111 		/* Find the end of the name. */
1112 		++arg;
1113 		name = arg;
1114 		len = get_env_len(&arg);
1115 		if (len == 0)
1116 		    EMSG2(_(e_invarg2), name - 1);
1117 		else
1118 		{
1119 		    if (*skipwhite(arg) != '=')
1120 			EMSG(_(e_letunexp));
1121 		    else
1122 		    {
1123 			cc = name[len];
1124 			name[len] = NUL;
1125 			p = get_var_string(&retvar);
1126 			vim_setenv(name, p);
1127 			if (STRICMP(name, "HOME") == 0)
1128 			    init_homedir();
1129 			else if (didset_vim && STRICMP(name, "VIM") == 0)
1130 			    didset_vim = FALSE;
1131 			else if (didset_vimruntime
1132 					  && STRICMP(name, "VIMRUNTIME") == 0)
1133 			    didset_vimruntime = FALSE;
1134 			name[len] = cc;
1135 		    }
1136 		}
1137 	    }
1138 
1139 	    /*
1140 	     * ":let &option = expr": Set option value.
1141 	     * ":let &l:option = expr": Set local option value.
1142 	     * ":let &g:option = expr": Set global option value.
1143 	     */
1144 	    else if (*arg == '&')
1145 	    {
1146 		int opt_flags;
1147 
1148 		/*
1149 		 * Find the end of the name;
1150 		 */
1151 		p = find_option_end(&arg, &opt_flags);
1152 		if (p == NULL || *skipwhite(p) != '=')
1153 		    EMSG(_(e_letunexp));
1154 		else
1155 		{
1156 		    c1 = *p;
1157 		    *p = NUL;
1158 		    set_option_value(arg, get_var_number(&retvar),
1159 					  get_var_string(&retvar), opt_flags);
1160 		    *p = c1;		    /* put back for error messages */
1161 		}
1162 	    }
1163 
1164 	    /*
1165 	     * ":let @r = expr": Set register contents.
1166 	     */
1167 	    else if (*arg == '@')
1168 	    {
1169 		++arg;
1170 		if (*skipwhite(arg + 1) != '=')
1171 		    EMSG(_(e_letunexp));
1172 		else
1173 		    write_reg_contents(*arg == '@' ? '"' : *arg,
1174 					  get_var_string(&retvar), -1, FALSE);
1175 	    }
1176 
1177 	    /*
1178 	     * ":let var = expr": Set internal variable.
1179 	     */
1180 	    else if (eval_isnamec(*arg) && !VIM_ISDIGIT(*arg))
1181 	    {
1182 		/* Find the end of the name. */
1183 		p = find_name_end(arg, &expr_start, &expr_end);
1184 
1185 		if (*skipwhite(p) != '=')
1186 		    EMSG(_(e_letunexp));
1187 		else if (p - arg == 13
1188 				    && STRNCMP(arg, "b:changedtick", 13) == 0)
1189 		    EMSG2(_(e_readonlyvar), arg);
1190 #ifdef FEAT_MAGIC_BRACES
1191 		else if (expr_start != NULL)
1192 		{
1193 		    char_u  *temp_string;
1194 
1195 		    temp_string = make_expanded_name(arg, expr_start,
1196 								 expr_end, p);
1197 		    if (temp_string == NULL)
1198 		    {
1199 			/*
1200 			 * Report an invalid expression in braces, unless the
1201 			 * expression evaluation has been cancelled due to an
1202 			 * aborting error, an interrupt, or an exception.
1203 			 */
1204 			if (!aborting())
1205 			    EMSG2(_(e_invarg2), arg);
1206 		    }
1207 		    else
1208 		    {
1209 			set_var(temp_string, &retvar);
1210 			vim_free(temp_string);
1211 		    }
1212 		}
1213 #endif
1214 		else
1215 		{
1216 		    c1 = *p;
1217 		    *p = NUL;
1218 		    set_var(arg, &retvar);
1219 		    *p = c1;		/* put char back for error messages */
1220 		}
1221 	    }
1222 
1223 	    else
1224 	    {
1225 		EMSG2(_(e_invarg2), arg);
1226 	    }
1227 
1228 	    clear_var(&retvar);
1229 	}
1230     }
1231 }
1232 
1233 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
1234 
1235     void
1236 set_context_for_expression(xp, arg, cmdidx)
1237     expand_T	*xp;
1238     char_u	*arg;
1239     cmdidx_T	cmdidx;
1240 {
1241     int		got_eq = FALSE;
1242     int		c;
1243 
1244     xp->xp_context = cmdidx == CMD_let ? EXPAND_USER_VARS
1245 				       : cmdidx == CMD_call ? EXPAND_FUNCTIONS
1246 				       : EXPAND_EXPRESSION;
1247     while ((xp->xp_pattern = vim_strpbrk(arg,
1248 				  (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL)
1249     {
1250 	c = *xp->xp_pattern;
1251 	if (c == '&')
1252 	{
1253 	    c = xp->xp_pattern[1];
1254 	    if (c == '&')
1255 	    {
1256 		++xp->xp_pattern;
1257 		xp->xp_context = cmdidx != CMD_let || got_eq
1258 					 ? EXPAND_EXPRESSION : EXPAND_NOTHING;
1259 	    }
1260 	    else if (c != ' ')
1261 		xp->xp_context = EXPAND_SETTINGS;
1262 	}
1263 	else if (c == '$')
1264 	{
1265 	    /* environment variable */
1266 	    xp->xp_context = EXPAND_ENV_VARS;
1267 	}
1268 	else if (c == '=')
1269 	{
1270 	    got_eq = TRUE;
1271 	    xp->xp_context = EXPAND_EXPRESSION;
1272 	}
1273 	else if (c == '<'
1274 		&& xp->xp_context == EXPAND_FUNCTIONS
1275 		&& vim_strchr(xp->xp_pattern, '(') == NULL)
1276 	{
1277 	    /* Function name can start with "<SNR>" */
1278 	    break;
1279 	}
1280 	else if (cmdidx != CMD_let || got_eq)
1281 	{
1282 	    if (c == '"')	    /* string */
1283 	    {
1284 		while ((c = *++xp->xp_pattern) != NUL && c != '"')
1285 		    if (c == '\\' && xp->xp_pattern[1] != NUL)
1286 			++xp->xp_pattern;
1287 		xp->xp_context = EXPAND_NOTHING;
1288 	    }
1289 	    else if (c == '\'')	    /* literal string */
1290 	    {
1291 		while ((c = *++xp->xp_pattern) != NUL && c != '\'')
1292 		    /* skip */ ;
1293 		xp->xp_context = EXPAND_NOTHING;
1294 	    }
1295 	    else if (c == '|')
1296 	    {
1297 		if (xp->xp_pattern[1] == '|')
1298 		{
1299 		    ++xp->xp_pattern;
1300 		    xp->xp_context = EXPAND_EXPRESSION;
1301 		}
1302 		else
1303 		    xp->xp_context = EXPAND_COMMANDS;
1304 	    }
1305 	    else
1306 		xp->xp_context = EXPAND_EXPRESSION;
1307 	}
1308 	else
1309 	    xp->xp_context = EXPAND_NOTHING;
1310 	arg = xp->xp_pattern;
1311 	if (*arg != NUL)
1312 	    while ((c = *++arg) != NUL && (c == ' ' || c == '\t'))
1313 		/* skip */ ;
1314     }
1315     xp->xp_pattern = arg;
1316 }
1317 
1318 #endif /* FEAT_CMDL_COMPL */
1319 
1320 /*
1321  * ":1,25call func(arg1, arg2)"	function call.
1322  */
1323     void
1324 ex_call(eap)
1325     exarg_T	*eap;
1326 {
1327     char_u	*arg = eap->arg;
1328     char_u	*startarg;
1329     char_u	*alias;
1330     char_u	*name;
1331     var		retvar;
1332     int		len;
1333     linenr_T	lnum;
1334     int		doesrange;
1335     int		failed = FALSE;
1336 
1337     name = arg;
1338     len = get_func_len(&arg, &alias, !eap->skip);
1339     if (len == 0)
1340 	goto end;
1341     if (alias != NULL)
1342 	name = alias;
1343 
1344     startarg = arg;
1345     retvar.var_type = VAR_UNKNOWN;	/* clear_var() uses this */
1346 
1347     if (*startarg != '(')
1348     {
1349 	EMSG2(_("E107: Missing braces: %s"), name);
1350 	goto end;
1351     }
1352 
1353     /*
1354      * When skipping, evaluate the function once, to find the end of the
1355      * arguments.
1356      * When the function takes a range, this is discovered after the first
1357      * call, and the loop is broken.
1358      */
1359     if (eap->skip)
1360     {
1361 	++emsg_skip;
1362 	lnum = eap->line2;	/* do it once, also with an invalid range */
1363     }
1364     else
1365 	lnum = eap->line1;
1366     for ( ; lnum <= eap->line2; ++lnum)
1367     {
1368 	if (!eap->skip && eap->addr_count > 0)
1369 	{
1370 	    curwin->w_cursor.lnum = lnum;
1371 	    curwin->w_cursor.col = 0;
1372 	}
1373 	arg = startarg;
1374 	if (get_func_var(name, len, &retvar, &arg,
1375 		      eap->line1, eap->line2, &doesrange, !eap->skip) == FAIL)
1376 	{
1377 	    failed = TRUE;
1378 	    break;
1379 	}
1380 	clear_var(&retvar);
1381 	if (doesrange || eap->skip)
1382 	    break;
1383 	/* Stop when immediately aborting on error, or when an interrupt
1384 	 * occurred or an exception was thrown but not caught.  get_func_var()
1385 	 * returned OK, so that the check for trailing characters below is
1386 	 * executed. */
1387 	if (aborting())
1388 	    break;
1389     }
1390     if (eap->skip)
1391 	--emsg_skip;
1392 
1393     if (!failed)
1394     {
1395 	/* Check for trailing illegal characters and a following command. */
1396 	if (!ends_excmd(*arg))
1397 	{
1398 	    emsg_severe = TRUE;
1399 	    EMSG(_(e_trailing));
1400 	}
1401 	else
1402 	    eap->nextcmd = check_nextcmd(arg);
1403     }
1404 
1405 end:
1406     if (alias != NULL)
1407 	vim_free(alias);
1408 }
1409 
1410 /*
1411  * ":unlet[!] var1 ... " command.
1412  */
1413     void
1414 ex_unlet(eap)
1415     exarg_T	*eap;
1416 {
1417     char_u	*arg = eap->arg;
1418     char_u	*name_end;
1419     char_u	cc;
1420     char_u	*expr_start;
1421     char_u	*expr_end;
1422     int		error = FALSE;
1423 
1424     do
1425     {
1426 	/* Find the end of the name. */
1427 	name_end = find_name_end(arg, &expr_start, &expr_end);
1428 
1429 	if (!vim_iswhite(*name_end) && !ends_excmd(*name_end))
1430 	{
1431 	    emsg_severe = TRUE;
1432 	    EMSG(_(e_trailing));
1433 	    break;
1434 	}
1435 
1436 	if (!error && !eap->skip)
1437 	{
1438 #ifdef FEAT_MAGIC_BRACES
1439 	    if (expr_start != NULL)
1440 	    {
1441 		char_u  *temp_string;
1442 
1443 		temp_string = make_expanded_name(arg, expr_start,
1444 							 expr_end, name_end);
1445 		if (temp_string == NULL)
1446 		{
1447 		    /*
1448 		     * Report an invalid expression in braces, unless the
1449 		     * expression evaluation has been cancelled due to an
1450 		     * aborting error, an interrupt, or an exception.
1451 		     */
1452 		    if (!aborting())
1453 		    {
1454 			emsg_severe = TRUE;
1455 			EMSG2(_(e_invarg2), arg);
1456 			break;
1457 		    }
1458 		    error = TRUE;
1459 		}
1460 		else
1461 		{
1462 		    if (do_unlet(temp_string) == FAIL && !eap->forceit)
1463 		    {
1464 			EMSG2(_("E108: No such variable: \"%s\""), temp_string);
1465 			error = TRUE;
1466 		    }
1467 		    vim_free(temp_string);
1468 		}
1469 	    }
1470 	    else
1471 #endif
1472 	    {
1473 		cc = *name_end;
1474 		*name_end = NUL;
1475 
1476 		if (do_unlet(arg) == FAIL && !eap->forceit)
1477 		{
1478 		    EMSG2(_("E108: No such variable: \"%s\""), arg);
1479 		    error = TRUE;
1480 		}
1481 
1482 		*name_end = cc;
1483 	    }
1484 	}
1485 	arg = skipwhite(name_end);
1486     } while (!ends_excmd(*arg));
1487 
1488     eap->nextcmd = check_nextcmd(arg);
1489 }
1490 
1491 /*
1492  * "unlet" a variable.  Return OK if it existed, FAIL if not.
1493  */
1494     int
1495 do_unlet(name)
1496     char_u	*name;
1497 {
1498     VAR		v;
1499 
1500     v = find_var(name, TRUE);
1501     if (v != NULL)
1502     {
1503 	var_free_one(v);
1504 	return OK;
1505     }
1506     return FAIL;
1507 }
1508 
1509 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO)
1510 /*
1511  * Delete all "menutrans_" variables.
1512  */
1513     void
1514 del_menutrans_vars()
1515 {
1516     int		i;
1517 
1518     for (i = 0; i < variables.ga_len; ++i)
1519 	if (VAR_ENTRY(i).var_name != NULL
1520 		&& STRNCMP(VAR_ENTRY(i).var_name, "menutrans_", 10) == 0)
1521 	    var_free_one(&VAR_ENTRY(i));
1522 }
1523 #endif
1524 
1525 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
1526 
1527 /*
1528  * Local string buffer for the next two functions to store a variable name
1529  * with its prefix. Allocated in cat_prefix_varname(), freed later in
1530  * get_user_var_name().
1531  */
1532 
1533 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name));
1534 
1535 static char_u	*varnamebuf = NULL;
1536 static int	varnamebuflen = 0;
1537 
1538 /*
1539  * Function to concatenate a prefix and a variable name.
1540  */
1541     static char_u *
1542 cat_prefix_varname(prefix, name)
1543     int		prefix;
1544     char_u	*name;
1545 {
1546     int		len;
1547 
1548     len = (int)STRLEN(name) + 3;
1549     if (len > varnamebuflen)
1550     {
1551 	vim_free(varnamebuf);
1552 	len += 10;			/* some additional space */
1553 	varnamebuf = alloc(len);
1554 	if (varnamebuf == NULL)
1555 	{
1556 	    varnamebuflen = 0;
1557 	    return NULL;
1558 	}
1559 	varnamebuflen = len;
1560     }
1561     *varnamebuf = prefix;
1562     varnamebuf[1] = ':';
1563     STRCPY(varnamebuf + 2, name);
1564     return varnamebuf;
1565 }
1566 
1567 /*
1568  * Function given to ExpandGeneric() to obtain the list of user defined
1569  * (global/buffer/window/built-in) variable names.
1570  */
1571 /*ARGSUSED*/
1572     char_u *
1573 get_user_var_name(xp, idx)
1574     expand_T	*xp;
1575     int		idx;
1576 {
1577     static int	gidx;
1578     static int	bidx;
1579     static int	widx;
1580     static int	vidx;
1581     char_u	*name;
1582 
1583     if (idx == 0)
1584 	gidx = bidx = widx = vidx = 0;
1585     if (gidx < variables.ga_len)			/* Global variables */
1586     {
1587 	while ((name = VAR_ENTRY(gidx++).var_name) == NULL
1588 		&& gidx < variables.ga_len)
1589 	    /* skip */;
1590 	if (name != NULL)
1591 	{
1592 	    if (STRNCMP("g:", xp->xp_pattern, 2) == 0)
1593 		return cat_prefix_varname('g', name);
1594 	    else
1595 		return name;
1596 	}
1597     }
1598     if (bidx < curbuf->b_vars.ga_len)		/* Current buffer variables */
1599     {
1600 	while ((name = BVAR_ENTRY(bidx++).var_name) == NULL
1601 		&& bidx < curbuf->b_vars.ga_len)
1602 	    /* skip */;
1603 	if (name != NULL)
1604 	    return cat_prefix_varname('b', name);
1605     }
1606     if (bidx == curbuf->b_vars.ga_len)
1607     {
1608 	++bidx;
1609 	return (char_u *)"b:changedtick";
1610     }
1611     if (widx < curwin->w_vars.ga_len)		/* Current window variables */
1612     {
1613 	while ((name = WVAR_ENTRY(widx++).var_name) == NULL
1614 		&& widx < curwin->w_vars.ga_len)
1615 	    /* skip */;
1616 	if (name != NULL)
1617 	    return cat_prefix_varname('w', name);
1618     }
1619     if (vidx < VV_LEN)				      /* Built-in variables */
1620 	return cat_prefix_varname('v', (char_u *)vimvars[vidx++].name);
1621 
1622     vim_free(varnamebuf);
1623     varnamebuf = NULL;
1624     varnamebuflen = 0;
1625     return NULL;
1626 }
1627 
1628 #endif /* FEAT_CMDL_COMPL */
1629 
1630 /*
1631  * types for expressions.
1632  */
1633 typedef enum
1634 {
1635     TYPE_UNKNOWN = 0
1636     , TYPE_EQUAL	/* == */
1637     , TYPE_NEQUAL	/* != */
1638     , TYPE_GREATER	/* >  */
1639     , TYPE_GEQUAL	/* >= */
1640     , TYPE_SMALLER	/* <  */
1641     , TYPE_SEQUAL	/* <= */
1642     , TYPE_MATCH	/* =~ */
1643     , TYPE_NOMATCH	/* !~ */
1644 } exptype_T;
1645 
1646 /*
1647  * The "evaluate" argument: When FALSE, the argument is only parsed but not
1648  * executed.  The function may return OK, but the retvar will be of type
1649  * VAR_UNKNOWN.  The function still returns FAIL for a syntax error.
1650  */
1651 
1652 /*
1653  * Handle zero level expression.
1654  * This calls eval1() and handles error message and nextcmd.
1655  * Return OK or FAIL.
1656  */
1657     static int
1658 eval0(arg, retvar, nextcmd, evaluate)
1659     char_u	*arg;
1660     VAR		retvar;
1661     char_u	**nextcmd;
1662     int		evaluate;
1663 {
1664     int		ret;
1665     char_u	*p;
1666 
1667     p = skipwhite(arg);
1668     ret = eval1(&p, retvar, evaluate);
1669     if (ret == FAIL || !ends_excmd(*p))
1670     {
1671 	if (ret != FAIL)
1672 	    clear_var(retvar);
1673 	/*
1674 	 * Report the invalid expression unless the expression evaluation has
1675 	 * been cancelled due to an aborting error, an interrupt, or an
1676 	 * exception.
1677 	 */
1678 	if (!aborting())
1679 	    EMSG2(_(e_invexpr2), arg);
1680 	ret = FAIL;
1681     }
1682     if (nextcmd != NULL)
1683 	*nextcmd = check_nextcmd(p);
1684 
1685     return ret;
1686 }
1687 
1688 /*
1689  * Handle top level expression:
1690  *	expr1 ? expr0 : expr0
1691  *
1692  * "arg" must point to the first non-white of the expression.
1693  * "arg" is advanced to the next non-white after the recognized expression.
1694  *
1695  * Return OK or FAIL.
1696  */
1697     static int
1698 eval1(arg, retvar, evaluate)
1699     char_u	**arg;
1700     VAR		retvar;
1701     int		evaluate;
1702 {
1703     int		result;
1704     var		var2;
1705 
1706     /*
1707      * Get the first variable.
1708      */
1709     if (eval2(arg, retvar, evaluate) == FAIL)
1710 	return FAIL;
1711 
1712     if ((*arg)[0] == '?')
1713     {
1714 	result = FALSE;
1715 	if (evaluate)
1716 	{
1717 	    if (get_var_number(retvar) != 0)
1718 		result = TRUE;
1719 	    clear_var(retvar);
1720 	}
1721 
1722 	/*
1723 	 * Get the second variable.
1724 	 */
1725 	*arg = skipwhite(*arg + 1);
1726 	if (eval1(arg, retvar, evaluate && result) == FAIL) /* recursive! */
1727 	    return FAIL;
1728 
1729 	/*
1730 	 * Check for the ":".
1731 	 */
1732 	if ((*arg)[0] != ':')
1733 	{
1734 	    EMSG(_("E109: Missing ':' after '?'"));
1735 	    if (evaluate && result)
1736 		clear_var(retvar);
1737 	    return FAIL;
1738 	}
1739 
1740 	/*
1741 	 * Get the third variable.
1742 	 */
1743 	*arg = skipwhite(*arg + 1);
1744 	if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */
1745 	{
1746 	    if (evaluate && result)
1747 		clear_var(retvar);
1748 	    return FAIL;
1749 	}
1750 	if (evaluate && !result)
1751 	    *retvar = var2;
1752     }
1753 
1754     return OK;
1755 }
1756 
1757 /*
1758  * Handle first level expression:
1759  *	expr2 || expr2 || expr2	    logical OR
1760  *
1761  * "arg" must point to the first non-white of the expression.
1762  * "arg" is advanced to the next non-white after the recognized expression.
1763  *
1764  * Return OK or FAIL.
1765  */
1766     static int
1767 eval2(arg, retvar, evaluate)
1768     char_u	**arg;
1769     VAR		retvar;
1770     int		evaluate;
1771 {
1772     var		var2;
1773     long	result;
1774     int		first;
1775 
1776     /*
1777      * Get the first variable.
1778      */
1779     if (eval3(arg, retvar, evaluate) == FAIL)
1780 	return FAIL;
1781 
1782     /*
1783      * Repeat until there is no following "||".
1784      */
1785     first = TRUE;
1786     result = FALSE;
1787     while ((*arg)[0] == '|' && (*arg)[1] == '|')
1788     {
1789 	if (evaluate && first)
1790 	{
1791 	    if (get_var_number(retvar) != 0)
1792 		result = TRUE;
1793 	    clear_var(retvar);
1794 	    first = FALSE;
1795 	}
1796 
1797 	/*
1798 	 * Get the second variable.
1799 	 */
1800 	*arg = skipwhite(*arg + 2);
1801 	if (eval3(arg, &var2, evaluate && !result) == FAIL)
1802 	    return FAIL;
1803 
1804 	/*
1805 	 * Compute the result.
1806 	 */
1807 	if (evaluate && !result)
1808 	{
1809 	    if (get_var_number(&var2) != 0)
1810 		result = TRUE;
1811 	    clear_var(&var2);
1812 	}
1813 	if (evaluate)
1814 	{
1815 	    retvar->var_type = VAR_NUMBER;
1816 	    retvar->var_val.var_number = result;
1817 	}
1818     }
1819 
1820     return OK;
1821 }
1822 
1823 /*
1824  * Handle second level expression:
1825  *	expr3 && expr3 && expr3	    logical AND
1826  *
1827  * "arg" must point to the first non-white of the expression.
1828  * "arg" is advanced to the next non-white after the recognized expression.
1829  *
1830  * Return OK or FAIL.
1831  */
1832     static int
1833 eval3(arg, retvar, evaluate)
1834     char_u	**arg;
1835     VAR		retvar;
1836     int		evaluate;
1837 {
1838     var		var2;
1839     long	result;
1840     int		first;
1841 
1842     /*
1843      * Get the first variable.
1844      */
1845     if (eval4(arg, retvar, evaluate) == FAIL)
1846 	return FAIL;
1847 
1848     /*
1849      * Repeat until there is no following "&&".
1850      */
1851     first = TRUE;
1852     result = TRUE;
1853     while ((*arg)[0] == '&' && (*arg)[1] == '&')
1854     {
1855 	if (evaluate && first)
1856 	{
1857 	    if (get_var_number(retvar) == 0)
1858 		result = FALSE;
1859 	    clear_var(retvar);
1860 	    first = FALSE;
1861 	}
1862 
1863 	/*
1864 	 * Get the second variable.
1865 	 */
1866 	*arg = skipwhite(*arg + 2);
1867 	if (eval4(arg, &var2, evaluate && result) == FAIL)
1868 	    return FAIL;
1869 
1870 	/*
1871 	 * Compute the result.
1872 	 */
1873 	if (evaluate && result)
1874 	{
1875 	    if (get_var_number(&var2) == 0)
1876 		result = FALSE;
1877 	    clear_var(&var2);
1878 	}
1879 	if (evaluate)
1880 	{
1881 	    retvar->var_type = VAR_NUMBER;
1882 	    retvar->var_val.var_number = result;
1883 	}
1884     }
1885 
1886     return OK;
1887 }
1888 
1889 /*
1890  * Handle third level expression:
1891  *	var1 == var2
1892  *	var1 =~ var2
1893  *	var1 != var2
1894  *	var1 !~ var2
1895  *	var1 > var2
1896  *	var1 >= var2
1897  *	var1 < var2
1898  *	var1 <= var2
1899  *
1900  * "arg" must point to the first non-white of the expression.
1901  * "arg" is advanced to the next non-white after the recognized expression.
1902  *
1903  * Return OK or FAIL.
1904  */
1905     static int
1906 eval4(arg, retvar, evaluate)
1907     char_u	**arg;
1908     VAR		retvar;
1909     int		evaluate;
1910 {
1911     var		var2;
1912     char_u	*p;
1913     int		i;
1914     exptype_T	type = TYPE_UNKNOWN;
1915     int		len = 2;
1916     long	n1, n2;
1917     char_u	*s1, *s2;
1918     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
1919     regmatch_T	regmatch;
1920     int		ic;
1921     char_u	*save_cpo;
1922 
1923     /*
1924      * Get the first variable.
1925      */
1926     if (eval5(arg, retvar, evaluate) == FAIL)
1927 	return FAIL;
1928 
1929     p = *arg;
1930     switch (p[0])
1931     {
1932 	case '=':   if (p[1] == '=')
1933 			type = TYPE_EQUAL;
1934 		    else if (p[1] == '~')
1935 			type = TYPE_MATCH;
1936 		    break;
1937 	case '!':   if (p[1] == '=')
1938 			type = TYPE_NEQUAL;
1939 		    else if (p[1] == '~')
1940 			type = TYPE_NOMATCH;
1941 		    break;
1942 	case '>':   if (p[1] != '=')
1943 		    {
1944 			type = TYPE_GREATER;
1945 			len = 1;
1946 		    }
1947 		    else
1948 			type = TYPE_GEQUAL;
1949 		    break;
1950 	case '<':   if (p[1] != '=')
1951 		    {
1952 			type = TYPE_SMALLER;
1953 			len = 1;
1954 		    }
1955 		    else
1956 			type = TYPE_SEQUAL;
1957 		    break;
1958     }
1959 
1960     /*
1961      * If there is a comparitive operator, use it.
1962      */
1963     if (type != TYPE_UNKNOWN)
1964     {
1965 	/* extra question mark appended: ignore case */
1966 	if (p[len] == '?')
1967 	{
1968 	    ic = TRUE;
1969 	    ++len;
1970 	}
1971 	/* extra '#' appended: match case */
1972 	else if (p[len] == '#')
1973 	{
1974 	    ic = FALSE;
1975 	    ++len;
1976 	}
1977 	/* nothing appened: use 'ignorecase' */
1978 	else
1979 	    ic = p_ic;
1980 
1981 	/*
1982 	 * Get the second variable.
1983 	 */
1984 	*arg = skipwhite(p + len);
1985 	if (eval5(arg, &var2, evaluate) == FAIL)
1986 	{
1987 	    clear_var(retvar);
1988 	    return FAIL;
1989 	}
1990 
1991 	if (evaluate)
1992 	{
1993 	    /*
1994 	     * If one of the two variables is a number, compare as a number.
1995 	     * When using "=~" or "!~", always compare as string.
1996 	     */
1997 	    if ((retvar->var_type == VAR_NUMBER || var2.var_type == VAR_NUMBER)
1998 		    && type != TYPE_MATCH && type != TYPE_NOMATCH)
1999 	    {
2000 		n1 = get_var_number(retvar);
2001 		n2 = get_var_number(&var2);
2002 		switch (type)
2003 		{
2004 		    case TYPE_EQUAL:    n1 = (n1 == n2); break;
2005 		    case TYPE_NEQUAL:   n1 = (n1 != n2); break;
2006 		    case TYPE_GREATER:  n1 = (n1 > n2); break;
2007 		    case TYPE_GEQUAL:   n1 = (n1 >= n2); break;
2008 		    case TYPE_SMALLER:  n1 = (n1 < n2); break;
2009 		    case TYPE_SEQUAL:   n1 = (n1 <= n2); break;
2010 		    case TYPE_UNKNOWN:
2011 		    case TYPE_MATCH:
2012 		    case TYPE_NOMATCH:  break;  /* avoid gcc warning */
2013 		}
2014 	    }
2015 	    else
2016 	    {
2017 		s1 = get_var_string_buf(retvar, buf1);
2018 		s2 = get_var_string_buf(&var2, buf2);
2019 		if (type != TYPE_MATCH && type != TYPE_NOMATCH)
2020 		    i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
2021 		else
2022 		    i = 0;
2023 		n1 = FALSE;
2024 		switch (type)
2025 		{
2026 		    case TYPE_EQUAL:    n1 = (i == 0); break;
2027 		    case TYPE_NEQUAL:   n1 = (i != 0); break;
2028 		    case TYPE_GREATER:  n1 = (i > 0); break;
2029 		    case TYPE_GEQUAL:   n1 = (i >= 0); break;
2030 		    case TYPE_SMALLER:  n1 = (i < 0); break;
2031 		    case TYPE_SEQUAL:   n1 = (i <= 0); break;
2032 
2033 		    case TYPE_MATCH:
2034 		    case TYPE_NOMATCH:
2035 			    /* avoid 'l' flag in 'cpoptions' */
2036 			    save_cpo = p_cpo;
2037 			    p_cpo = (char_u *)"";
2038 			    regmatch.regprog = vim_regcomp(s2,
2039 							RE_MAGIC + RE_STRING);
2040 			    regmatch.rm_ic = ic;
2041 			    if (regmatch.regprog != NULL)
2042 			    {
2043 				n1 = vim_regexec_nl(&regmatch, s1, (colnr_T)0);
2044 				vim_free(regmatch.regprog);
2045 				if (type == TYPE_NOMATCH)
2046 				    n1 = !n1;
2047 			    }
2048 			    p_cpo = save_cpo;
2049 			    break;
2050 
2051 		    case TYPE_UNKNOWN:  break;  /* avoid gcc warning */
2052 		}
2053 	    }
2054 	    clear_var(retvar);
2055 	    clear_var(&var2);
2056 	    retvar->var_type = VAR_NUMBER;
2057 	    retvar->var_val.var_number = n1;
2058 	}
2059     }
2060 
2061     return OK;
2062 }
2063 
2064 /*
2065  * Handle fourth level expression:
2066  *	+	number addition
2067  *	-	number subtraction
2068  *	.	string concatenation
2069  *
2070  * "arg" must point to the first non-white of the expression.
2071  * "arg" is advanced to the next non-white after the recognized expression.
2072  *
2073  * Return OK or FAIL.
2074  */
2075     static int
2076 eval5(arg, retvar, evaluate)
2077     char_u	**arg;
2078     VAR		retvar;
2079     int		evaluate;
2080 {
2081     var		var2;
2082     int		op;
2083     long	n1, n2;
2084     char_u	*s1, *s2;
2085     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
2086     char_u	*p;
2087 
2088     /*
2089      * Get the first variable.
2090      */
2091     if (eval6(arg, retvar, evaluate) == FAIL)
2092 	return FAIL;
2093 
2094     /*
2095      * Repeat computing, until no '+', '-' or '.' is following.
2096      */
2097     for (;;)
2098     {
2099 	op = **arg;
2100 	if (op != '+' && op != '-' && op != '.')
2101 	    break;
2102 
2103 	/*
2104 	 * Get the second variable.
2105 	 */
2106 	*arg = skipwhite(*arg + 1);
2107 	if (eval6(arg, &var2, evaluate) == FAIL)
2108 	{
2109 	    clear_var(retvar);
2110 	    return FAIL;
2111 	}
2112 
2113 	if (evaluate)
2114 	{
2115 	    /*
2116 	     * Compute the result.
2117 	     */
2118 	    if (op == '.')
2119 	    {
2120 		s1 = get_var_string_buf(retvar, buf1);
2121 		s2 = get_var_string_buf(&var2, buf2);
2122 		op = (int)STRLEN(s1);
2123 		p = alloc((unsigned)(op + STRLEN(s2) + 1));
2124 		if (p != NULL)
2125 		{
2126 		    STRCPY(p, s1);
2127 		    STRCPY(p + op, s2);
2128 		}
2129 		clear_var(retvar);
2130 		retvar->var_type = VAR_STRING;
2131 		retvar->var_val.var_string = p;
2132 	    }
2133 	    else
2134 	    {
2135 		n1 = get_var_number(retvar);
2136 		n2 = get_var_number(&var2);
2137 		clear_var(retvar);
2138 		if (op == '+')
2139 		    n1 = n1 + n2;
2140 		else
2141 		    n1 = n1 - n2;
2142 		retvar->var_type = VAR_NUMBER;
2143 		retvar->var_val.var_number = n1;
2144 	    }
2145 	    clear_var(&var2);
2146 	}
2147     }
2148     return OK;
2149 }
2150 
2151 /*
2152  * Handle fifth level expression:
2153  *	*	number multiplication
2154  *	/	number division
2155  *	%	number modulo
2156  *
2157  * "arg" must point to the first non-white of the expression.
2158  * "arg" is advanced to the next non-white after the recognized expression.
2159  *
2160  * Return OK or FAIL.
2161  */
2162     static int
2163 eval6(arg, retvar, evaluate)
2164     char_u	**arg;
2165     VAR		retvar;
2166     int		evaluate;
2167 {
2168     var		var2;
2169     int		op;
2170     long	n1, n2;
2171 
2172     /*
2173      * Get the first variable.
2174      */
2175     if (eval7(arg, retvar, evaluate) == FAIL)
2176 	return FAIL;
2177 
2178     /*
2179      * Repeat computing, until no '*', '/' or '%' is following.
2180      */
2181     for (;;)
2182     {
2183 	op = **arg;
2184 	if (op != '*' && op != '/' && op != '%')
2185 	    break;
2186 
2187 	if (evaluate)
2188 	{
2189 	    n1 = get_var_number(retvar);
2190 	    clear_var(retvar);
2191 	}
2192 	else
2193 	    n1 = 0;
2194 
2195 	/*
2196 	 * Get the second variable.
2197 	 */
2198 	*arg = skipwhite(*arg + 1);
2199 	if (eval7(arg, &var2, evaluate) == FAIL)
2200 	    return FAIL;
2201 
2202 	if (evaluate)
2203 	{
2204 	    n2 = get_var_number(&var2);
2205 	    clear_var(&var2);
2206 
2207 	    /*
2208 	     * Compute the result.
2209 	     */
2210 	    if (op == '*')
2211 		n1 = n1 * n2;
2212 	    else if (op == '/')
2213 	    {
2214 		if (n2 == 0)	/* give an error message? */
2215 		    n1 = 0x7fffffffL;
2216 		else
2217 		    n1 = n1 / n2;
2218 	    }
2219 	    else
2220 	    {
2221 		if (n2 == 0)	/* give an error message? */
2222 		    n1 = 0;
2223 		else
2224 		    n1 = n1 % n2;
2225 	    }
2226 	    retvar->var_type = VAR_NUMBER;
2227 	    retvar->var_val.var_number = n1;
2228 	}
2229     }
2230 
2231     return OK;
2232 }
2233 
2234 /*
2235  * Handle sixth level expression:
2236  *  number		number constant
2237  *  "string"		string contstant
2238  *  'string'		literal string contstant
2239  *  &option-name	option value
2240  *  @r			register contents
2241  *  identifier		variable value
2242  *  function()		function call
2243  *  $VAR		environment variable
2244  *  (expression)	nested expression
2245  *
2246  *  Also handle:
2247  *  ! in front		logical NOT
2248  *  - in front		unary minus
2249  *  + in front		unary plus (ignored)
2250  *  trailing []		subscript in String
2251  *
2252  * "arg" must point to the first non-white of the expression.
2253  * "arg" is advanced to the next non-white after the recognized expression.
2254  *
2255  * Return OK or FAIL.
2256  */
2257     static int
2258 eval7(arg, retvar, evaluate)
2259     char_u	**arg;
2260     VAR		retvar;
2261     int		evaluate;
2262 {
2263     var		var2;
2264     long	n;
2265     int		len;
2266     char_u	*s;
2267     int		val;
2268     char_u	*start_leader, *end_leader;
2269     int		ret = OK;
2270     char_u	*alias;
2271 
2272     /*
2273      * Initialise variable so that clear_var() can't mistake this for a string
2274      * and free a string that isn't there.
2275      */
2276     retvar->var_type = VAR_UNKNOWN;
2277 
2278     /*
2279      * Skip '!' and '-' characters.  They are handled later.
2280      */
2281     start_leader = *arg;
2282     while (**arg == '!' || **arg == '-' || **arg == '+')
2283 	*arg = skipwhite(*arg + 1);
2284     end_leader = *arg;
2285 
2286     switch (**arg)
2287     {
2288     /*
2289      * Number constant.
2290      */
2291     case '0':
2292     case '1':
2293     case '2':
2294     case '3':
2295     case '4':
2296     case '5':
2297     case '6':
2298     case '7':
2299     case '8':
2300     case '9':
2301 		vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL);
2302 		*arg += len;
2303 		if (evaluate)
2304 		{
2305 		    retvar->var_type = VAR_NUMBER;
2306 		    retvar->var_val.var_number = n;
2307 		}
2308 		break;
2309 
2310     /*
2311      * String constant: "string".
2312      */
2313     case '"':	ret = get_string_var(arg, retvar, evaluate);
2314 		break;
2315 
2316     /*
2317      * Literal string constant: 'string'.
2318      */
2319     case '\'':	ret = get_lit_string_var(arg, retvar, evaluate);
2320 		break;
2321 
2322     /*
2323      * Option value: &name
2324      */
2325     case '&':	ret = get_option_var(arg, retvar, evaluate);
2326 		break;
2327 
2328     /*
2329      * Environment variable: $VAR.
2330      */
2331     case '$':	ret = get_env_var(arg, retvar, evaluate);
2332 		break;
2333 
2334     /*
2335      * Register contents: @r.
2336      */
2337     case '@':	++*arg;
2338 		if (evaluate)
2339 		{
2340 		    retvar->var_type = VAR_STRING;
2341 		    retvar->var_val.var_string = get_reg_contents(**arg, FALSE);
2342 		}
2343 		if (**arg != NUL)
2344 		    ++*arg;
2345 		break;
2346 
2347     /*
2348      * nested expression: (expression).
2349      */
2350     case '(':	*arg = skipwhite(*arg + 1);
2351 		ret = eval1(arg, retvar, evaluate);	/* recursive! */
2352 		if (**arg == ')')
2353 		    ++*arg;
2354 		else if (ret == OK)
2355 		{
2356 		    EMSG(_("E110: Missing ')'"));
2357 		    clear_var(retvar);
2358 		    ret = FAIL;
2359 		}
2360 		break;
2361 
2362     /*
2363      * Must be a variable or function name then.
2364      */
2365     default:	s = *arg;
2366 		len = get_func_len(arg, &alias, evaluate);
2367 		if (alias != NULL)
2368 		    s = alias;
2369 
2370 		if (len == 0)
2371 		    ret = FAIL;
2372 		else
2373 		{
2374 		    if (**arg == '(')		/* recursive! */
2375 		    {
2376 			ret = get_func_var(s, len, retvar, arg,
2377 				  curwin->w_cursor.lnum, curwin->w_cursor.lnum,
2378 				  &len, evaluate);
2379 			/* Stop the expression evaluation when immediately
2380 			 * aborting on error, or when an interrupt occurred or
2381 			 * an exception was thrown but not caught. */
2382 			if (aborting())
2383 			{
2384 			    if (ret == OK)
2385 				clear_var(retvar);
2386 			    ret = FAIL;
2387 			}
2388 		    }
2389 		    else if (evaluate)
2390 			ret = get_var_var(s, len, retvar);
2391 		}
2392 
2393 		if (alias != NULL)
2394 		    vim_free(alias);
2395 
2396 		break;
2397     }
2398     *arg = skipwhite(*arg);
2399 
2400     /*
2401      * Handle expr[expr] subscript.
2402      */
2403     if (**arg == '[' && ret == OK)
2404     {
2405 	/*
2406 	 * Get the variable from inside the [].
2407 	 */
2408 	*arg = skipwhite(*arg + 1);
2409 	if (eval1(arg, &var2, evaluate) == FAIL)	/* recursive! */
2410 	{
2411 	    clear_var(retvar);
2412 	    return FAIL;
2413 	}
2414 
2415 	/* Check for the ']'. */
2416 	if (**arg != ']')
2417 	{
2418 	    EMSG(_("E111: Missing ']'"));
2419 	    clear_var(retvar);
2420 	    clear_var(&var2);
2421 	    return FAIL;
2422 	}
2423 
2424 	if (evaluate)
2425 	{
2426 	    n = get_var_number(&var2);
2427 	    clear_var(&var2);
2428 
2429 	    /*
2430 	     * The resulting variable is a string of a single character.
2431 	     * If the index is too big or negative, the result is empty.
2432 	     */
2433 	    s = get_var_string(retvar);
2434 	    if (n >= (long)STRLEN(s) || n < 0)
2435 		s = NULL;
2436 	    else
2437 		s = vim_strnsave(s + n, 1);
2438 	    clear_var(retvar);
2439 	    retvar->var_type = VAR_STRING;
2440 	    retvar->var_val.var_string = s;
2441 	}
2442 	*arg = skipwhite(*arg + 1);	/* skip the ']' */
2443     }
2444 
2445     /*
2446      * Apply logical NOT and unary '-', from right to left, ignore '+'.
2447      */
2448     if (ret == OK && evaluate && end_leader > start_leader)
2449     {
2450 	val = get_var_number(retvar);
2451 	while (end_leader > start_leader)
2452 	{
2453 	    --end_leader;
2454 	    if (*end_leader == '!')
2455 		val = !val;
2456 	    else if (*end_leader == '-')
2457 		val = -val;
2458 	}
2459 	clear_var(retvar);
2460 	retvar->var_type = VAR_NUMBER;
2461 	retvar->var_val.var_number = val;
2462     }
2463 
2464     return ret;
2465 }
2466 
2467 /*
2468  * Get an option value.
2469  * "arg" points to the '&' or '+' before the option name.
2470  * "arg" is advanced to character after the option name.
2471  * Return OK or FAIL.
2472  */
2473     static int
2474 get_option_var(arg, retvar, evaluate)
2475     char_u	**arg;
2476     VAR		retvar;		/* when NULL, only check if option exists */
2477     int		evaluate;
2478 {
2479     char_u	*option_end;
2480     long	numval;
2481     char_u	*stringval;
2482     int		opt_type;
2483     int		c;
2484     int		working = (**arg == '+');    /* has("+option") */
2485     int		ret = OK;
2486     int		opt_flags;
2487 
2488     /*
2489      * Isolate the option name and find its value.
2490      */
2491     option_end = find_option_end(arg, &opt_flags);
2492     if (option_end == NULL)
2493     {
2494 	if (retvar != NULL)
2495 	    EMSG2(_("E112: Option name missing: %s"), *arg);
2496 	return FAIL;
2497     }
2498 
2499     if (!evaluate)
2500     {
2501 	*arg = option_end;
2502 	return OK;
2503     }
2504 
2505     c = *option_end;
2506     *option_end = NUL;
2507     opt_type = get_option_value(*arg, &numval,
2508 			       retvar == NULL ? NULL : &stringval, opt_flags);
2509 
2510     if (opt_type == -3)			/* invalid name */
2511     {
2512 	if (retvar != NULL)
2513 	    EMSG2(_("E113: Unknown option: %s"), *arg);
2514 	ret = FAIL;
2515     }
2516     else if (retvar != NULL)
2517     {
2518 	if (opt_type == -2)		/* hidden string option */
2519 	{
2520 	    retvar->var_type = VAR_STRING;
2521 	    retvar->var_val.var_string = NULL;
2522 	}
2523 	else if (opt_type == -1)	/* hidden number option */
2524 	{
2525 	    retvar->var_type = VAR_NUMBER;
2526 	    retvar->var_val.var_number = 0;
2527 	}
2528 	else if (opt_type == 1)		/* number option */
2529 	{
2530 	    retvar->var_type = VAR_NUMBER;
2531 	    retvar->var_val.var_number = numval;
2532 	}
2533 	else				/* string option */
2534 	{
2535 	    retvar->var_type = VAR_STRING;
2536 	    retvar->var_val.var_string = stringval;
2537 	}
2538     }
2539     else if (working && (opt_type == -2 || opt_type == -1))
2540 	ret = FAIL;
2541 
2542     *option_end = c;		    /* put back for error messages */
2543     *arg = option_end;
2544 
2545     return ret;
2546 }
2547 
2548 /*
2549  * Allocate a variable for a string constant.
2550  * Return OK or FAIL.
2551  */
2552     static int
2553 get_string_var(arg, retvar, evaluate)
2554     char_u	**arg;
2555     VAR		retvar;
2556     int		evaluate;
2557 {
2558     char_u	*p;
2559     char_u	*name;
2560     int		i;
2561     int		extra = 0;
2562 
2563     /*
2564      * Find the end of the string, skipping backslashed characters.
2565      */
2566     for (p = *arg + 1; *p && *p != '"'; ++p)
2567     {
2568 	if (*p == '\\' && p[1] != NUL)
2569 	{
2570 	    ++p;
2571 	    /* A "\<x>" form occupies at least 4 characters, and produces up
2572 	     * to 6 characters: reserve space for 2 extra */
2573 	    if (*p == '<')
2574 		extra += 2;
2575 	}
2576 #ifdef FEAT_MBYTE
2577 	if (has_mbyte)
2578 	    p += (*mb_ptr2len_check)(p) - 1;
2579 #endif
2580     }
2581 
2582     if (*p != '"')
2583     {
2584 	EMSG2(_("E114: Missing quote: %s"), *arg);
2585 	return FAIL;
2586     }
2587 
2588     /* If only parsing, set *arg and return here */
2589     if (!evaluate)
2590     {
2591 	*arg = p + 1;
2592 	return OK;
2593     }
2594 
2595     /*
2596      * Copy the string into allocated memory, handling backslashed
2597      * characters.
2598      */
2599     name = alloc((unsigned)(p - *arg + extra));
2600     if (name == NULL)
2601 	return FAIL;
2602 
2603     i = 0;
2604     for (p = *arg + 1; *p && *p != '"'; ++p)
2605     {
2606 	if (*p == '\\')
2607 	{
2608 	    switch (*++p)
2609 	    {
2610 		case 'b': name[i++] = BS; break;
2611 		case 'e': name[i++] = ESC; break;
2612 		case 'f': name[i++] = FF; break;
2613 		case 'n': name[i++] = NL; break;
2614 		case 'r': name[i++] = CAR; break;
2615 		case 't': name[i++] = TAB; break;
2616 
2617 		case 'X': /* hex: "\x1", "\x12" */
2618 		case 'x':
2619 		case 'u': /* Unicode: "\u0023" */
2620 		case 'U':
2621 			  if (vim_isxdigit(p[1]))
2622 			  {
2623 			      int	n, nr;
2624 			      int	c = toupper(*p);
2625 
2626 			      if (c == 'X')
2627 				  n = 2;
2628 			      else
2629 				  n = 4;
2630 			      nr = 0;
2631 			      while (--n >= 0 && vim_isxdigit(p[1]))
2632 			      {
2633 				  ++p;
2634 				  nr = (nr << 4) + hex2nr(*p);
2635 			      }
2636 #ifdef FEAT_MBYTE
2637 			      /* For "\u" store the number according to
2638 			       * 'encoding'. */
2639 			      if (c != 'X')
2640 				  i += (*mb_char2bytes)(nr, name + i);
2641 			      else
2642 #endif
2643 				  name[i++] = nr;
2644 			  }
2645 			  else
2646 			      name[i++] = *p;
2647 			  break;
2648 
2649 			  /* octal: "\1", "\12", "\123" */
2650 		case '0':
2651 		case '1':
2652 		case '2':
2653 		case '3':
2654 		case '4':
2655 		case '5':
2656 		case '6':
2657 		case '7': name[i] = *p - '0';
2658 			  if (p[1] >= '0' && p[1] <= '7')
2659 			  {
2660 			      ++p;
2661 			      name[i] = (name[i] << 3) + *p - '0';
2662 			      if (p[1] >= '0' && p[1] <= '7')
2663 			      {
2664 				  ++p;
2665 				  name[i] = (name[i] << 3) + *p - '0';
2666 			      }
2667 			  }
2668 			  ++i;
2669 			  break;
2670 
2671 			    /* Special key, e.g.: "\<C-W>" */
2672 		case '<': extra = trans_special(&p, name + i, TRUE);
2673 			  if (extra != 0)
2674 			  {
2675 			      i += extra;
2676 			      --p;
2677 			      break;
2678 			  }
2679 			  /* FALLTHROUGH */
2680 
2681 		default:  name[i++] = *p;
2682 			  break;
2683 	    }
2684 	}
2685 	else
2686 	    name[i++] = *p;
2687 
2688 #ifdef FEAT_MBYTE
2689 	/* For a multi-byte character copy the bytes after the first one. */
2690 	if (has_mbyte)
2691 	{
2692 	    int	l = (*mb_ptr2len_check)(p);
2693 
2694 	    while (--l > 0)
2695 		name[i++] = *++p;
2696 	}
2697 #endif
2698     }
2699     name[i] = NUL;
2700     *arg = p + 1;
2701 
2702     retvar->var_type = VAR_STRING;
2703     retvar->var_val.var_string = name;
2704 
2705     return OK;
2706 }
2707 
2708 /*
2709  * Allocate a variable for an backtick-string constant.
2710  * Return OK or FAIL.
2711  */
2712     static int
2713 get_lit_string_var(arg, retvar, evaluate)
2714     char_u	**arg;
2715     VAR		retvar;
2716     int		evaluate;
2717 {
2718     char_u	*p;
2719     char_u	*name;
2720 
2721     /*
2722      * Find the end of the string.
2723      */
2724     p = vim_strchr(*arg + 1, '\'');
2725     if (p == NULL)
2726     {
2727 	EMSG2(_("E115: Missing quote: %s"), *arg);
2728 	return FAIL;
2729     }
2730 
2731     if (evaluate)
2732     {
2733 	/*
2734 	 * Copy the string into allocated memory.
2735 	 */
2736 	name = vim_strnsave(*arg + 1, (int)(p - (*arg + 1)));
2737 	if (name == NULL)
2738 	    return FAIL;
2739 
2740 	retvar->var_type = VAR_STRING;
2741 	retvar->var_val.var_string = name;
2742     }
2743 
2744     *arg = p + 1;
2745 
2746     return OK;
2747 }
2748 
2749 /*
2750  * Get the value of an environment variable.
2751  * "arg" is pointing to the '$'.  It is advanced to after the name.
2752  * If the environment variable was not set, silently assume it is empty.
2753  * Always return OK.
2754  */
2755     static int
2756 get_env_var(arg, retvar, evaluate)
2757     char_u	**arg;
2758     VAR		retvar;
2759     int		evaluate;
2760 {
2761     char_u	*string = NULL;
2762     int		len;
2763     int		cc;
2764     char_u	*name;
2765 
2766     ++*arg;
2767     name = *arg;
2768     len = get_env_len(arg);
2769     if (evaluate)
2770     {
2771 	if (len != 0)
2772 	{
2773 	    cc = name[len];
2774 	    name[len] = NUL;
2775 	    /* first try mch_getenv(), fast for normal environment vars */
2776 	    string = mch_getenv(name);
2777 	    if (string != NULL && *string != NUL)
2778 		string = vim_strsave(string);
2779 	    else
2780 	    {
2781 		/* next try expanding things like $VIM and ${HOME} */
2782 		string = expand_env_save(name - 1);
2783 		if (string != NULL && *string == '$')
2784 		{
2785 		    vim_free(string);
2786 		    string = NULL;
2787 		}
2788 	    }
2789 	    name[len] = cc;
2790 	}
2791 	retvar->var_type = VAR_STRING;
2792 	retvar->var_val.var_string = string;
2793     }
2794 
2795     return OK;
2796 }
2797 
2798 /*
2799  * Array with names and number of arguments of all internal functions
2800  * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH!
2801  */
2802 static struct fst
2803 {
2804     char	*f_name;	/* function name */
2805     char	f_min_argc;	/* minimal number of arguments */
2806     char	f_max_argc;	/* maximal number of arguments */
2807     void	(*f_func) __ARGS((VAR args, VAR rvar)); /* impl. function */
2808 } functions[] =
2809 {
2810     {"append",		2, 2, f_append},
2811     {"argc",		0, 0, f_argc},
2812     {"argidx",		0, 0, f_argidx},
2813     {"argv",		1, 1, f_argv},
2814     {"browse",		4, 4, f_browse},
2815     {"bufexists",	1, 1, f_bufexists},
2816     {"buffer_exists",	1, 1, f_bufexists},	/* obsolete */
2817     {"buffer_name",	1, 1, f_bufname},	/* obsolete */
2818     {"buffer_number",	1, 1, f_bufnr},		/* obsolete */
2819     {"buflisted",	1, 1, f_buflisted},
2820     {"bufloaded",	1, 1, f_bufloaded},
2821     {"bufname",		1, 1, f_bufname},
2822     {"bufnr",		1, 1, f_bufnr},
2823     {"bufwinnr",	1, 1, f_bufwinnr},
2824     {"byte2line",	1, 1, f_byte2line},
2825     {"byteidx",		2, 2, f_byteidx},
2826     {"char2nr",		1, 1, f_char2nr},
2827     {"cindent",		1, 1, f_cindent},
2828     {"col",		1, 1, f_col},
2829     {"confirm",		1, 4, f_confirm},
2830     {"cscope_connection",0,3, f_cscope_connection},
2831     {"cursor",		2, 2, f_cursor},
2832     {"delete",		1, 1, f_delete},
2833     {"did_filetype",	0, 0, f_did_filetype},
2834     {"escape",		2, 2, f_escape},
2835     {"eventhandler",	0, 0, f_eventhandler},
2836     {"executable",	1, 1, f_executable},
2837     {"exists",		1, 1, f_exists},
2838     {"expand",		1, 2, f_expand},
2839     {"file_readable",	1, 1, f_filereadable},	/* obsolete */
2840     {"filereadable",	1, 1, f_filereadable},
2841     {"filewritable",	1, 1, f_filewritable},
2842     {"finddir",		1, 3, f_finddir},
2843     {"findfile",	1, 3, f_findfile},
2844     {"fnamemodify",	2, 2, f_fnamemodify},
2845     {"foldclosed",	1, 1, f_foldclosed},
2846     {"foldclosedend",	1, 1, f_foldclosedend},
2847     {"foldlevel",	1, 1, f_foldlevel},
2848     {"foldtext",	0, 0, f_foldtext},
2849     {"foreground",	0, 0, f_foreground},
2850     {"getbufvar",	2, 2, f_getbufvar},
2851     {"getchar",		0, 1, f_getchar},
2852     {"getcharmod",	0, 0, f_getcharmod},
2853     {"getcmdline",	0, 0, f_getcmdline},
2854     {"getcmdpos",	0, 0, f_getcmdpos},
2855     {"getcwd",		0, 0, f_getcwd},
2856     {"getfsize",	1, 1, f_getfsize},
2857     {"getftime",	1, 1, f_getftime},
2858     {"getline",		1, 1, f_getline},
2859     {"getreg",		0, 1, f_getreg},
2860     {"getregtype",	0, 1, f_getregtype},
2861     {"getwinposx",	0, 0, f_getwinposx},
2862     {"getwinposy",	0, 0, f_getwinposy},
2863     {"getwinvar",	2, 2, f_getwinvar},
2864     {"glob",		1, 1, f_glob},
2865     {"globpath",	2, 2, f_globpath},
2866     {"has",		1, 1, f_has},
2867     {"hasmapto",	1, 2, f_hasmapto},
2868     {"highlightID",	1, 1, f_hlID},		/* obsolete */
2869     {"highlight_exists",1, 1, f_hlexists},	/* obsolete */
2870     {"histadd",		2, 2, f_histadd},
2871     {"histdel",		1, 2, f_histdel},
2872     {"histget",		1, 2, f_histget},
2873     {"histnr",		1, 1, f_histnr},
2874     {"hlID",		1, 1, f_hlID},
2875     {"hlexists",	1, 1, f_hlexists},
2876     {"hostname",	0, 0, f_hostname},
2877     {"iconv",		3, 3, f_iconv},
2878     {"indent",		1, 1, f_indent},
2879     {"input",		1, 2, f_input},
2880     {"inputdialog",	1, 3, f_inputdialog},
2881     {"inputrestore",	0, 0, f_inputrestore},
2882     {"inputsave",	0, 0, f_inputsave},
2883     {"inputsecret",	1, 2, f_inputsecret},
2884     {"isdirectory",	1, 1, f_isdirectory},
2885     {"last_buffer_nr",	0, 0, f_last_buffer_nr},/* obsolete */
2886     {"libcall",		3, 3, f_libcall},
2887     {"libcallnr",	3, 3, f_libcallnr},
2888     {"line",		1, 1, f_line},
2889     {"line2byte",	1, 1, f_line2byte},
2890     {"lispindent",	1, 1, f_lispindent},
2891     {"localtime",	0, 0, f_localtime},
2892     {"maparg",		1, 2, f_maparg},
2893     {"mapcheck",	1, 2, f_mapcheck},
2894     {"match",		2, 4, f_match},
2895     {"matchend",	2, 4, f_matchend},
2896     {"matchstr",	2, 4, f_matchstr},
2897     {"mode",		0, 0, f_mode},
2898     {"nextnonblank",	1, 1, f_nextnonblank},
2899     {"nr2char",		1, 1, f_nr2char},
2900     {"prevnonblank",	1, 1, f_prevnonblank},
2901     {"remote_expr",	2, 3, f_remote_expr},
2902     {"remote_foreground", 1, 1, f_remote_foreground},
2903     {"remote_peek",	1, 2, f_remote_peek},
2904     {"remote_read",	1, 1, f_remote_read},
2905     {"remote_send",	2, 3, f_remote_send},
2906     {"rename",		2, 2, f_rename},
2907     {"repeat",		2, 2, f_repeat},
2908     {"resolve",		1, 1, f_resolve},
2909     {"search",		1, 2, f_search},
2910     {"searchpair",	3, 5, f_searchpair},
2911     {"server2client",	2, 2, f_server2client},
2912     {"serverlist",	0, 0, f_serverlist},
2913     {"setbufvar",	3, 3, f_setbufvar},
2914     {"setcmdpos",	1, 1, f_setcmdpos},
2915     {"setline",		2, 2, f_setline},
2916     {"setreg",		2, 3, f_setreg},
2917     {"setwinvar",	3, 3, f_setwinvar},
2918     {"simplify",	1, 1, f_simplify},
2919 #ifdef HAVE_STRFTIME
2920     {"strftime",	1, 2, f_strftime},
2921 #endif
2922     {"stridx",		2, 2, f_stridx},
2923     {"strlen",		1, 1, f_strlen},
2924     {"strpart",		2, 3, f_strpart},
2925     {"strridx",		2, 2, f_strridx},
2926     {"strtrans",	1, 1, f_strtrans},
2927     {"submatch",	1, 1, f_submatch},
2928     {"substitute",	4, 4, f_substitute},
2929     {"synID",		3, 3, f_synID},
2930     {"synIDattr",	2, 3, f_synIDattr},
2931     {"synIDtrans",	1, 1, f_synIDtrans},
2932     {"system",		1, 1, f_system},
2933     {"tempname",	0, 0, f_tempname},
2934     {"tolower",		1, 1, f_tolower},
2935     {"toupper",		1, 1, f_toupper},
2936     {"tr",		3, 3, f_tr},
2937     {"type",		1, 1, f_type},
2938     {"virtcol",		1, 1, f_virtcol},
2939     {"visualmode",	0, 1, f_visualmode},
2940     {"winbufnr",	1, 1, f_winbufnr},
2941     {"wincol",		0, 0, f_wincol},
2942     {"winheight",	1, 1, f_winheight},
2943     {"winline",		0, 0, f_winline},
2944     {"winnr",		0, 0, f_winnr},
2945     {"winrestcmd",	0, 0, f_winrestcmd},
2946     {"winwidth",	1, 1, f_winwidth},
2947 };
2948 
2949 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
2950 
2951 /*
2952  * Function given to ExpandGeneric() to obtain the list of internal
2953  * or user defined function names.
2954  */
2955     char_u *
2956 get_function_name(xp, idx)
2957     expand_T	*xp;
2958     int		idx;
2959 {
2960     static int	intidx = -1;
2961     char_u	*name;
2962 
2963     if (idx == 0)
2964 	intidx = -1;
2965     if (intidx < 0)
2966     {
2967 	name = get_user_func_name(xp, idx);
2968 	if (name != NULL)
2969 	    return name;
2970     }
2971     if (++intidx < (int)(sizeof(functions) / sizeof(struct fst)))
2972     {
2973 	STRCPY(IObuff, functions[intidx].f_name);
2974 	STRCAT(IObuff, "(");
2975 	if (functions[intidx].f_max_argc == 0)
2976 	    STRCAT(IObuff, ")");
2977 	return IObuff;
2978     }
2979 
2980     return NULL;
2981 }
2982 
2983 /*
2984  * Function given to ExpandGeneric() to obtain the list of internal or
2985  * user defined variable or function names.
2986  */
2987 /*ARGSUSED*/
2988     char_u *
2989 get_expr_name(xp, idx)
2990     expand_T	*xp;
2991     int		idx;
2992 {
2993     static int	intidx = -1;
2994     char_u	*name;
2995 
2996     if (idx == 0)
2997 	intidx = -1;
2998     if (intidx < 0)
2999     {
3000 	name = get_function_name(xp, idx);
3001 	if (name != NULL)
3002 	    return name;
3003     }
3004     return get_user_var_name(xp, ++intidx);
3005 }
3006 
3007 #endif /* FEAT_CMDL_COMPL */
3008 
3009 /*
3010  * Find internal function in table above.
3011  * Return index, or -1 if not found
3012  */
3013     static int
3014 find_internal_func(name)
3015     char_u	*name;		/* name of the function */
3016 {
3017     int		first = 0;
3018     int		last = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
3019     int		cmp;
3020     int		x;
3021 
3022     /*
3023      * Find the function name in the table. Binary search.
3024      */
3025     while (first <= last)
3026     {
3027 	x = first + ((unsigned)(last - first) >> 1);
3028 	cmp = STRCMP(name, functions[x].f_name);
3029 	if (cmp < 0)
3030 	    last = x - 1;
3031 	else if (cmp > 0)
3032 	    first = x + 1;
3033 	else
3034 	    return x;
3035     }
3036     return -1;
3037 }
3038 
3039 /*
3040  * Allocate a variable for the result of a function.
3041  * Return OK or FAIL.
3042  */
3043     static int
3044 get_func_var(name, len, retvar, arg, firstline, lastline, doesrange, evaluate)
3045     char_u	*name;		/* name of the function */
3046     int		len;		/* length of "name" */
3047     VAR		retvar;
3048     char_u	**arg;		/* argument, pointing to the '(' */
3049     linenr_T	firstline;	/* first line of range */
3050     linenr_T	lastline;	/* last line of range */
3051     int		*doesrange;	/* return: function handled range */
3052     int		evaluate;
3053 {
3054     char_u	*argp;
3055     int		ret = OK;
3056 #define MAX_FUNC_ARGS	20
3057     var		argvars[MAX_FUNC_ARGS];	/* vars for arguments */
3058     int		argcount = 0;		/* number of arguments found */
3059 
3060     /*
3061      * Get the arguments.
3062      */
3063     argp = *arg;
3064     while (argcount < MAX_FUNC_ARGS)
3065     {
3066 	argp = skipwhite(argp + 1);	    /* skip the '(' or ',' */
3067 	if (*argp == ')' || *argp == ',' || *argp == NUL)
3068 	    break;
3069 	argvars[argcount].var_name = NULL;  /* the name is not stored */
3070 	if (eval1(&argp, &argvars[argcount], evaluate) == FAIL)
3071 	{
3072 	    ret = FAIL;
3073 	    break;
3074 	}
3075 	++argcount;
3076 	if (*argp != ',')
3077 	    break;
3078     }
3079     if (*argp == ')')
3080 	++argp;
3081     else
3082 	ret = FAIL;
3083 
3084     if (ret == OK)
3085 	ret = call_func(name, len, retvar, argcount, argvars,
3086 				    firstline, lastline, doesrange, evaluate);
3087     else if (!aborting())
3088 	EMSG2(_("E116: Invalid arguments for function %s"), name);
3089 
3090     while (--argcount >= 0)
3091 	clear_var(&argvars[argcount]);
3092 
3093     *arg = skipwhite(argp);
3094     return ret;
3095 }
3096 
3097 
3098 /*
3099  * Call a function with its resolved parameters
3100  * Return OK or FAIL.
3101  */
3102     static int
3103 call_func(name, len, retvar, argcount, argvars, firstline, lastline,
3104 							  doesrange, evaluate)
3105     char_u	*name;		/* name of the function */
3106     int		len;		/* length of "name" */
3107     VAR		retvar;		/* return value goes here */
3108     int		argcount;	/* number of "argvars" */
3109     VAR		argvars;	/* vars for arguments */
3110     linenr_T	firstline;	/* first line of range */
3111     linenr_T	lastline;	/* last line of range */
3112     int		*doesrange;	/* return: function handled range */
3113     int		evaluate;
3114 {
3115     int		ret = FAIL;
3116     static char *errors[] =
3117 		{N_("E117: Unknown function: %s"),
3118 		 N_("E118: Too many arguments for function: %s"),
3119 		 N_("E119: Not enough arguments for function: %s"),
3120 		 N_("E120: Using <SID> not in a script context: %s"),
3121 		};
3122 #define ERROR_UNKNOWN	0
3123 #define ERROR_TOOMANY	1
3124 #define ERROR_TOOFEW	2
3125 #define ERROR_SCRIPT	3
3126 #define ERROR_NONE	4
3127 #define ERROR_OTHER	5
3128     int		error = ERROR_NONE;
3129     int		i;
3130     int		llen;
3131     ufunc_T	*fp;
3132     int		cc;
3133 #define FLEN_FIXED 40
3134     char_u	fname_buf[FLEN_FIXED + 1];
3135     char_u	*fname;
3136 
3137     /*
3138      * In a script change <SID>name() and s:name() to K_SNR 123_name().
3139      * Change <SNR>123_name() to K_SNR 123_name().
3140      * Use fname_buf[] when it fits, otherwise allocate memory (slow).
3141      */
3142     cc = name[len];
3143     name[len] = NUL;
3144     llen = eval_fname_script(name);
3145     if (llen > 0)
3146     {
3147 	fname_buf[0] = K_SPECIAL;
3148 	fname_buf[1] = KS_EXTRA;
3149 	fname_buf[2] = (int)KE_SNR;
3150 	i = 3;
3151 	if (eval_fname_sid(name))	/* "<SID>" or "s:" */
3152 	{
3153 	    if (current_SID <= 0)
3154 		error = ERROR_SCRIPT;
3155 	    else
3156 	    {
3157 		sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID);
3158 		i = (int)STRLEN(fname_buf);
3159 	    }
3160 	}
3161 	if (i + STRLEN(name + llen) < FLEN_FIXED)
3162 	{
3163 	    STRCPY(fname_buf + i, name + llen);
3164 	    fname = fname_buf;
3165 	}
3166 	else
3167 	{
3168 	    fname = alloc((unsigned)(i + STRLEN(name + llen) + 1));
3169 	    if (fname == NULL)
3170 		error = ERROR_OTHER;
3171 	    else
3172 	    {
3173 		mch_memmove(fname, fname_buf, (size_t)i);
3174 		STRCPY(fname + i, name + llen);
3175 	    }
3176 	}
3177     }
3178     else
3179 	fname = name;
3180 
3181     *doesrange = FALSE;
3182 
3183 
3184     /* execute the function if no errors detected and executing */
3185     if (evaluate && error == ERROR_NONE)
3186     {
3187 	retvar->var_type = VAR_NUMBER;	/* default is number retvar */
3188 	error = ERROR_UNKNOWN;
3189 
3190 	if (!ASCII_ISLOWER(fname[0]))
3191 	{
3192 	    /*
3193 	     * User defined function.
3194 	     */
3195 	    fp = find_func(fname);
3196 #ifdef FEAT_AUTOCMD
3197 	    if (fp == NULL && apply_autocmds(EVENT_FUNCUNDEFINED,
3198 						    fname, fname, TRUE, NULL)
3199 #ifdef FEAT_EVAL
3200 		    && !aborting()
3201 #endif
3202 	       )
3203 	    {
3204 		/* executed an autocommand, search for function again */
3205 		fp = find_func(fname);
3206 	    }
3207 #endif
3208 	    if (fp != NULL)
3209 	    {
3210 		if (fp->flags & FC_RANGE)
3211 		    *doesrange = TRUE;
3212 		if (argcount < fp->args.ga_len)
3213 		    error = ERROR_TOOFEW;
3214 		else if (!fp->varargs && argcount > fp->args.ga_len)
3215 		    error = ERROR_TOOMANY;
3216 		else
3217 		{
3218 		    /*
3219 		     * Call the user function.
3220 		     * Save and restore search patterns, script variables and
3221 		     * redo buffer.
3222 		     */
3223 		    save_search_patterns();
3224 		    saveRedobuff();
3225 		    ++fp->calls;
3226 		    call_user_func(fp, argcount, argvars, retvar,
3227 							 firstline, lastline);
3228 		    --fp->calls;
3229 		    restoreRedobuff();
3230 		    restore_search_patterns();
3231 		    error = ERROR_NONE;
3232 		}
3233 	    }
3234 	}
3235 	else
3236 	{
3237 	    /*
3238 	     * Find the function name in the table, call its implementation.
3239 	     */
3240 	    i = find_internal_func(fname);
3241 	    if (i >= 0)
3242 	    {
3243 		if (argcount < functions[i].f_min_argc)
3244 		    error = ERROR_TOOFEW;
3245 		else if (argcount > functions[i].f_max_argc)
3246 		    error = ERROR_TOOMANY;
3247 		else
3248 		{
3249 		    argvars[argcount].var_type = VAR_UNKNOWN;
3250 		    functions[i].f_func(argvars, retvar);
3251 		    error = ERROR_NONE;
3252 		}
3253 	    }
3254 	}
3255 	/*
3256 	 * The function call (or "FuncUndefined" autocommand sequence) might
3257 	 * have been aborted by an error, an interrupt, or an explicitly thrown
3258 	 * exception that has not been caught so far.  This situation can be
3259 	 * tested for by calling aborting().  For an error in an internal
3260 	 * function or for the "E132" error in call_user_func(), however, the
3261 	 * throw point at which the "force_abort" flag (temporarily reset by
3262 	 * emsg()) is normally updated has not been reached yet. We need to
3263 	 * update that flag first to make aborting() reliable.
3264 	 */
3265 	update_force_abort();
3266     }
3267     if (error == ERROR_NONE)
3268 	ret = OK;
3269 
3270     /*
3271      * Report an error unless the argument evaluation or function call has been
3272      * cancelled due to an aborting error, an interrupt, or an exception.
3273      */
3274     if (error < ERROR_NONE && !aborting())
3275 	EMSG2((char_u *)_(errors[error]), name);
3276 
3277     name[len] = cc;
3278     if (fname != name && fname != fname_buf)
3279 	vim_free(fname);
3280 
3281     return ret;
3282 }
3283 
3284 /*********************************************
3285  * Implementation of the built-in functions
3286  */
3287 
3288 /*
3289  * "append(lnum, string)" function
3290  */
3291     static void
3292 f_append(argvars, retvar)
3293     VAR		argvars;
3294     VAR		retvar;
3295 {
3296     long	lnum;
3297 
3298     lnum = get_var_lnum(argvars);
3299     retvar->var_val.var_number = 1; /* Default: Failed */
3300 
3301     if (lnum >= 0
3302 	    && lnum <= curbuf->b_ml.ml_line_count
3303 	    && u_save(lnum, lnum + 1) == OK)
3304     {
3305 	ml_append(lnum, get_var_string(&argvars[1]), (colnr_T)0, FALSE);
3306 	if (curwin->w_cursor.lnum > lnum)
3307 	    ++curwin->w_cursor.lnum;
3308 	appended_lines_mark(lnum, 1L);
3309 	retvar->var_val.var_number = 0;
3310     }
3311 }
3312 
3313 /*
3314  * "argc()" function
3315  */
3316 /* ARGSUSED */
3317     static void
3318 f_argc(argvars, retvar)
3319     VAR		argvars;
3320     VAR		retvar;
3321 {
3322     retvar->var_val.var_number = ARGCOUNT;
3323 }
3324 
3325 /*
3326  * "argidx()" function
3327  */
3328 /* ARGSUSED */
3329     static void
3330 f_argidx(argvars, retvar)
3331     VAR		argvars;
3332     VAR		retvar;
3333 {
3334     retvar->var_val.var_number = curwin->w_arg_idx;
3335 }
3336 
3337 /*
3338  * "argv(nr)" function
3339  */
3340     static void
3341 f_argv(argvars, retvar)
3342     VAR		argvars;
3343     VAR		retvar;
3344 {
3345     int		idx;
3346 
3347     idx = get_var_number(&argvars[0]);
3348     if (idx >= 0 && idx < ARGCOUNT)
3349 	retvar->var_val.var_string = vim_strsave(alist_name(&ARGLIST[idx]));
3350     else
3351 	retvar->var_val.var_string = NULL;
3352     retvar->var_type = VAR_STRING;
3353 }
3354 
3355 /*
3356  * "browse(save, title, initdir, default)" function
3357  */
3358 /* ARGSUSED */
3359     static void
3360 f_browse(argvars, retvar)
3361     VAR		argvars;
3362     VAR		retvar;
3363 {
3364 #ifdef FEAT_BROWSE
3365     int		save;
3366     char_u	*title;
3367     char_u	*initdir;
3368     char_u	*defname;
3369     char_u	buf[NUMBUFLEN];
3370     char_u	buf2[NUMBUFLEN];
3371 
3372     save = get_var_number(&argvars[0]);
3373     title = get_var_string(&argvars[1]);
3374     initdir = get_var_string_buf(&argvars[2], buf);
3375     defname = get_var_string_buf(&argvars[3], buf2);
3376 
3377     retvar->var_val.var_string =
3378 		 do_browse(save, title, defname, NULL, initdir, NULL, curbuf);
3379 #else
3380     retvar->var_val.var_string = NULL;
3381 #endif
3382     retvar->var_type = VAR_STRING;
3383 }
3384 
3385 /*
3386  * Find a buffer by number or exact name.
3387  */
3388     static buf_T *
3389 find_buffer(avar)
3390     VAR		avar;
3391 {
3392     buf_T	*buf = NULL;
3393     char_u	*name;
3394 
3395     if (avar->var_type == VAR_NUMBER)
3396 	buf = buflist_findnr((int)avar->var_val.var_number);
3397     else if (avar->var_val.var_string != NULL)
3398     {
3399 	/* First make the name into a full path name */
3400 	name = FullName_save(avar->var_val.var_string,
3401 #ifdef UNIX
3402 		TRUE	    /* force expansion, get rid of symbolic links */
3403 #else
3404 		FALSE
3405 #endif
3406 		);
3407 	if (name != NULL)
3408 	{
3409 	    buf = buflist_findname(name);
3410 	    vim_free(name);
3411 	}
3412 	if (buf == NULL)
3413 	{
3414 	    /* No full path name match, try a match with a URL or a "nofile"
3415 	     * buffer, these don't use the full path. */
3416 	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
3417 		if (buf->b_fname != NULL
3418 			&& (path_with_url(buf->b_fname)
3419 #ifdef FEAT_QUICKFIX
3420 			    || bt_nofile(buf)
3421 #endif
3422 			   )
3423 			&& STRCMP(buf->b_fname, avar->var_val.var_string) == 0)
3424 		    break;
3425 	}
3426     }
3427     return buf;
3428 }
3429 
3430 /*
3431  * "bufexists(expr)" function
3432  */
3433     static void
3434 f_bufexists(argvars, retvar)
3435     VAR		argvars;
3436     VAR		retvar;
3437 {
3438     retvar->var_val.var_number = (find_buffer(&argvars[0]) != NULL);
3439 }
3440 
3441 /*
3442  * "buflisted(expr)" function
3443  */
3444     static void
3445 f_buflisted(argvars, retvar)
3446     VAR		argvars;
3447     VAR		retvar;
3448 {
3449     buf_T	*buf;
3450 
3451     buf = find_buffer(&argvars[0]);
3452     retvar->var_val.var_number = (buf != NULL && buf->b_p_bl);
3453 }
3454 
3455 /*
3456  * "bufloaded(expr)" function
3457  */
3458     static void
3459 f_bufloaded(argvars, retvar)
3460     VAR		argvars;
3461     VAR		retvar;
3462 {
3463     buf_T	*buf;
3464 
3465     buf = find_buffer(&argvars[0]);
3466     retvar->var_val.var_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
3467 }
3468 
3469 /*
3470  * Get buffer by number or pattern.
3471  */
3472     static buf_T *
3473 get_buf_var(avar)
3474     VAR		avar;
3475 {
3476     char_u	*name = avar->var_val.var_string;
3477     int		save_magic;
3478     char_u	*save_cpo;
3479     buf_T	*buf;
3480 
3481     if (avar->var_type == VAR_NUMBER)
3482 	return buflist_findnr((int)avar->var_val.var_number);
3483     if (name == NULL || *name == NUL)
3484 	return curbuf;
3485     if (name[0] == '$' && name[1] == NUL)
3486 	return lastbuf;
3487 
3488     /* Ignore 'magic' and 'cpoptions' here to make scripts portable */
3489     save_magic = p_magic;
3490     p_magic = TRUE;
3491     save_cpo = p_cpo;
3492     p_cpo = (char_u *)"";
3493 
3494     buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name),
3495 								TRUE, FALSE));
3496 
3497     p_magic = save_magic;
3498     p_cpo = save_cpo;
3499 
3500     /* If not found, try expanding the name, like done for bufexists(). */
3501     if (buf == NULL)
3502 	buf = find_buffer(avar);
3503 
3504     return buf;
3505 }
3506 
3507 /*
3508  * "bufname(expr)" function
3509  */
3510     static void
3511 f_bufname(argvars, retvar)
3512     VAR		argvars;
3513     VAR		retvar;
3514 {
3515     buf_T	*buf;
3516 
3517     ++emsg_off;
3518     buf = get_buf_var(&argvars[0]);
3519     retvar->var_type = VAR_STRING;
3520     if (buf != NULL && buf->b_fname != NULL)
3521 	retvar->var_val.var_string = vim_strsave(buf->b_fname);
3522     else
3523 	retvar->var_val.var_string = NULL;
3524     --emsg_off;
3525 }
3526 
3527 /*
3528  * "bufnr(expr)" function
3529  */
3530     static void
3531 f_bufnr(argvars, retvar)
3532     VAR		argvars;
3533     VAR		retvar;
3534 {
3535     buf_T	*buf;
3536 
3537     ++emsg_off;
3538     buf = get_buf_var(&argvars[0]);
3539     if (buf != NULL)
3540 	retvar->var_val.var_number = buf->b_fnum;
3541     else
3542 	retvar->var_val.var_number = -1;
3543     --emsg_off;
3544 }
3545 
3546 /*
3547  * "bufwinnr(nr)" function
3548  */
3549     static void
3550 f_bufwinnr(argvars, retvar)
3551     VAR		argvars;
3552     VAR		retvar;
3553 {
3554 #ifdef FEAT_WINDOWS
3555     win_T	*wp;
3556     int		winnr = 0;
3557 #endif
3558     buf_T	*buf;
3559 
3560     ++emsg_off;
3561     buf = get_buf_var(&argvars[0]);
3562 #ifdef FEAT_WINDOWS
3563     for (wp = firstwin; wp; wp = wp->w_next)
3564     {
3565 	++winnr;
3566 	if (wp->w_buffer == buf)
3567 	    break;
3568     }
3569     retvar->var_val.var_number = (wp != NULL ? winnr : -1);
3570 #else
3571     retvar->var_val.var_number = (curwin->w_buffer == buf ? 1 : -1);
3572 #endif
3573     --emsg_off;
3574 }
3575 
3576 /*
3577  * "byte2line(byte)" function
3578  */
3579 /*ARGSUSED*/
3580     static void
3581 f_byte2line(argvars, retvar)
3582     VAR		argvars;
3583     VAR		retvar;
3584 {
3585 #ifndef FEAT_BYTEOFF
3586     retvar->var_val.var_number = -1;
3587 #else
3588     long	boff = 0;
3589 
3590     boff = get_var_number(&argvars[0]) - 1;
3591     if (boff < 0)
3592 	retvar->var_val.var_number = -1;
3593     else
3594 	retvar->var_val.var_number = ml_find_line_or_offset(curbuf,
3595 							  (linenr_T)0, &boff);
3596 #endif
3597 }
3598 
3599 /*
3600  * "byteidx()" function
3601  */
3602 /*ARGSUSED*/
3603     static void
3604 f_byteidx(argvars, retvar)
3605     VAR		argvars;
3606     VAR		retvar;
3607 {
3608 #ifdef FEAT_MBYTE
3609     char_u	*t;
3610 #endif
3611     char_u	*str;
3612     long	idx;
3613 
3614     str = get_var_string(&argvars[0]);
3615     idx = get_var_number(&argvars[1]);
3616     retvar->var_val.var_number = -1;
3617     if (idx < 0)
3618 	return;
3619 
3620 #ifdef FEAT_MBYTE
3621     t = str;
3622     for ( ; idx > 0; idx--)
3623     {
3624 	if (*t == NUL)		/* EOL reached */
3625 	    return;
3626 	t += mb_ptr2len_check(t);
3627     }
3628     retvar->var_val.var_number = t - str;
3629 #else
3630     if (idx <= STRLEN(str))
3631 	retvar->var_val.var_number = idx;
3632 #endif
3633 }
3634 
3635 /*
3636  * "char2nr(string)" function
3637  */
3638     static void
3639 f_char2nr(argvars, retvar)
3640     VAR		argvars;
3641     VAR		retvar;
3642 {
3643 #ifdef FEAT_MBYTE
3644     if (has_mbyte)
3645 	retvar->var_val.var_number =
3646 				  (*mb_ptr2char)(get_var_string(&argvars[0]));
3647     else
3648 #endif
3649     retvar->var_val.var_number = get_var_string(&argvars[0])[0];
3650 }
3651 
3652 /*
3653  * "cindent(lnum)" function
3654  */
3655     static void
3656 f_cindent(argvars, retvar)
3657     VAR		argvars;
3658     VAR		retvar;
3659 {
3660 #ifdef FEAT_CINDENT
3661     pos_T	pos;
3662     linenr_T	lnum;
3663 
3664     pos = curwin->w_cursor;
3665     lnum = get_var_lnum(argvars);
3666     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
3667     {
3668 	curwin->w_cursor.lnum = lnum;
3669 	retvar->var_val.var_number = get_c_indent();
3670 	curwin->w_cursor = pos;
3671     }
3672     else
3673 #endif
3674 	retvar->var_val.var_number = -1;
3675 }
3676 
3677 /*
3678  * "col(string)" function
3679  */
3680     static void
3681 f_col(argvars, retvar)
3682     VAR		argvars;
3683     VAR		retvar;
3684 {
3685     colnr_T	col = 0;
3686     pos_T	*fp;
3687 
3688     fp = var2fpos(&argvars[0], FALSE);
3689     if (fp != NULL)
3690     {
3691 	if (fp->col == MAXCOL)
3692 	{
3693 	    /* '> can be MAXCOL, get the length of the line then */
3694 	    if (fp->lnum <= curbuf->b_ml.ml_line_count)
3695 		col = STRLEN(ml_get(fp->lnum)) + 1;
3696 	    else
3697 		col = MAXCOL;
3698 	}
3699 	else
3700 	{
3701 	    col = fp->col + 1;
3702 #ifdef FEAT_VIRTUALEDIT
3703 	    /* col(".") when the cursor is on the NUL at the end of the line
3704 	     * because of "coladd" can be seen as an extra column. */
3705 	    if (virtual_active() && fp == &curwin->w_cursor)
3706 	    {
3707 		char_u	*p = ml_get_cursor();
3708 
3709 		if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p,
3710 				 curwin->w_virtcol - curwin->w_cursor.coladd))
3711 		{
3712 # ifdef FEAT_MBYTE
3713 		    int		l;
3714 
3715 		    if (*p != NUL && p[(l = (*mb_ptr2len_check)(p))] == NUL)
3716 			col += l;
3717 # else
3718 		    if (*p != NUL && p[1] == NUL)
3719 			++col;
3720 # endif
3721 		}
3722 	    }
3723 #endif
3724 	}
3725     }
3726     retvar->var_val.var_number = col;
3727 }
3728 
3729 /*
3730  * "confirm(message, buttons[, default [, type]])" function
3731  */
3732 /*ARGSUSED*/
3733     static void
3734 f_confirm(argvars, retvar)
3735     VAR		argvars;
3736     VAR		retvar;
3737 {
3738 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
3739     char_u	*message;
3740     char_u	*buttons = NULL;
3741     char_u	buf[NUMBUFLEN];
3742     char_u	buf2[NUMBUFLEN];
3743     int		def = 1;
3744     int		type = VIM_GENERIC;
3745     int		c;
3746 
3747     message = get_var_string(&argvars[0]);
3748     if (argvars[1].var_type != VAR_UNKNOWN)
3749     {
3750 	buttons = get_var_string_buf(&argvars[1], buf);
3751 	if (argvars[2].var_type != VAR_UNKNOWN)
3752 	{
3753 	    def = get_var_number(&argvars[2]);
3754 	    if (argvars[3].var_type != VAR_UNKNOWN)
3755 	    {
3756 		/* avoid that TOUPPER_ASC calls get_var_string_buf() twice */
3757 		c = *get_var_string_buf(&argvars[3], buf2);
3758 		switch (TOUPPER_ASC(c))
3759 		{
3760 		    case 'E': type = VIM_ERROR; break;
3761 		    case 'Q': type = VIM_QUESTION; break;
3762 		    case 'I': type = VIM_INFO; break;
3763 		    case 'W': type = VIM_WARNING; break;
3764 		    case 'G': type = VIM_GENERIC; break;
3765 		}
3766 	    }
3767 	}
3768     }
3769 
3770     if (buttons == NULL || *buttons == NUL)
3771 	buttons = (char_u *)_("&Ok");
3772 
3773     retvar->var_val.var_number = do_dialog(type, NULL, message, buttons,
3774 								   def, NULL);
3775 #else
3776     retvar->var_val.var_number = 0;
3777 #endif
3778 }
3779 
3780 
3781 /*
3782  * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
3783  *
3784  * Checks the existence of a cscope connection.
3785  */
3786 /*ARGSUSED*/
3787     static void
3788 f_cscope_connection(argvars, retvar)
3789     VAR		argvars;
3790     VAR		retvar;
3791 {
3792 #ifdef FEAT_CSCOPE
3793     int		num = 0;
3794     char_u	*dbpath = NULL;
3795     char_u	*prepend = NULL;
3796     char_u	buf[NUMBUFLEN];
3797 
3798     if (argvars[0].var_type != VAR_UNKNOWN
3799 	    && argvars[1].var_type != VAR_UNKNOWN)
3800     {
3801 	num = (int)get_var_number(&argvars[0]);
3802 	dbpath = get_var_string(&argvars[1]);
3803 	if (argvars[2].var_type != VAR_UNKNOWN)
3804 	    prepend = get_var_string_buf(&argvars[2], buf);
3805     }
3806 
3807     retvar->var_val.var_number = cs_connection(num, dbpath, prepend);
3808 #else
3809     retvar->var_val.var_number = 0;
3810 #endif
3811 }
3812 
3813 /*
3814  * "cursor(lnum, col)" function
3815  *
3816  * Moves the cursor to the specified line and column
3817  */
3818 /*ARGSUSED*/
3819     static void
3820 f_cursor(argvars, retvar)
3821     VAR		argvars;
3822     VAR		retvar;
3823 {
3824     long	line, col;
3825 
3826     line = get_var_lnum(argvars);
3827     if (line > 0)
3828 	curwin->w_cursor.lnum = line;
3829     col = get_var_number(&argvars[1]);
3830     if (col > 0)
3831 	curwin->w_cursor.col = col - 1;
3832 #ifdef FEAT_VIRTUALEDIT
3833     curwin->w_cursor.coladd = 0;
3834 #endif
3835 
3836     /* Make sure the cursor is in a valid position. */
3837     check_cursor();
3838 #ifdef FEAT_MBYTE
3839     /* Correct cursor for multi-byte character. */
3840     if (has_mbyte)
3841 	mb_adjust_cursor();
3842 #endif
3843 
3844     curwin->w_set_curswant = TRUE;
3845 }
3846 
3847 /*
3848  * "libcall()" function
3849  */
3850     static void
3851 f_libcall(argvars, retvar)
3852     VAR		argvars;
3853     VAR		retvar;
3854 {
3855     libcall_common(argvars, retvar, VAR_STRING);
3856 }
3857 
3858 /*
3859  * "libcallnr()" function
3860  */
3861     static void
3862 f_libcallnr(argvars, retvar)
3863     VAR		argvars;
3864     VAR		retvar;
3865 {
3866     libcall_common(argvars, retvar, VAR_NUMBER);
3867 }
3868 
3869     static void
3870 libcall_common(argvars, retvar, type)
3871     VAR		argvars;
3872     VAR		retvar;
3873     int		type;
3874 {
3875 #ifdef FEAT_LIBCALL
3876     char_u		*string_in;
3877     char_u		**string_result;
3878     int			nr_result;
3879 #endif
3880 
3881     retvar->var_type = type;
3882     if (type == VAR_NUMBER)
3883 	retvar->var_val.var_number = 0;
3884     else
3885 	retvar->var_val.var_string = NULL;
3886 
3887     if (check_restricted() || check_secure())
3888 	return;
3889 
3890 #ifdef FEAT_LIBCALL
3891     /* The first two args must be strings, otherwise its meaningless */
3892     if (argvars[0].var_type == VAR_STRING && argvars[1].var_type == VAR_STRING)
3893     {
3894 	if (argvars[2].var_type == VAR_NUMBER)
3895 	    string_in = NULL;
3896 	else
3897 	    string_in = argvars[2].var_val.var_string;
3898 	if (type == VAR_NUMBER)
3899 	    string_result = NULL;
3900 	else
3901 	    string_result = &retvar->var_val.var_string;
3902 	if (mch_libcall(argvars[0].var_val.var_string,
3903 			     argvars[1].var_val.var_string,
3904 			     string_in,
3905 			     argvars[2].var_val.var_number,
3906 			     string_result,
3907 			     &nr_result) == OK
3908 		&& type == VAR_NUMBER)
3909 	    retvar->var_val.var_number = nr_result;
3910     }
3911 #endif
3912 }
3913 
3914 /*
3915  * "delete()" function
3916  */
3917     static void
3918 f_delete(argvars, retvar)
3919     VAR		argvars;
3920     VAR		retvar;
3921 {
3922     if (check_restricted() || check_secure())
3923 	retvar->var_val.var_number = -1;
3924     else
3925 	retvar->var_val.var_number = mch_remove(get_var_string(&argvars[0]));
3926 }
3927 
3928 /*
3929  * "did_filetype()" function
3930  */
3931 /*ARGSUSED*/
3932     static void
3933 f_did_filetype(argvars, retvar)
3934     VAR		argvars;
3935     VAR		retvar;
3936 {
3937 #ifdef FEAT_AUTOCMD
3938     retvar->var_val.var_number = did_filetype;
3939 #else
3940     retvar->var_val.var_number = 0;
3941 #endif
3942 }
3943 
3944 /*
3945  * "escape({string}, {chars})" function
3946  */
3947     static void
3948 f_escape(argvars, retvar)
3949     VAR		argvars;
3950     VAR		retvar;
3951 {
3952     char_u	buf[NUMBUFLEN];
3953 
3954     retvar->var_val.var_string =
3955 	vim_strsave_escaped(get_var_string(&argvars[0]),
3956 		get_var_string_buf(&argvars[1], buf));
3957     retvar->var_type = VAR_STRING;
3958 }
3959 
3960 /*
3961  * "eventhandler()" function
3962  */
3963 /*ARGSUSED*/
3964     static void
3965 f_eventhandler(argvars, retvar)
3966     VAR		argvars;
3967     VAR		retvar;
3968 {
3969     retvar->var_val.var_number = vgetc_busy;
3970 }
3971 
3972 /*
3973  * "executable()" function
3974  */
3975     static void
3976 f_executable(argvars, retvar)
3977     VAR		argvars;
3978     VAR		retvar;
3979 {
3980     retvar->var_val.var_number = mch_can_exe(get_var_string(&argvars[0]));
3981 }
3982 
3983 /*
3984  * "exists()" function
3985  */
3986     static void
3987 f_exists(argvars, retvar)
3988     VAR		argvars;
3989     VAR		retvar;
3990 {
3991     char_u	*p;
3992     char_u	*name;
3993     int		n = FALSE;
3994     int		len = 0;
3995 
3996     p = get_var_string(&argvars[0]);
3997     if (*p == '$')			/* environment variable */
3998     {
3999 	/* first try "normal" environment variables (fast) */
4000 	if (mch_getenv(p + 1) != NULL)
4001 	    n = TRUE;
4002 	else
4003 	{
4004 	    /* try expanding things like $VIM and ${HOME} */
4005 	    p = expand_env_save(p);
4006 	    if (p != NULL && *p != '$')
4007 		n = TRUE;
4008 	    vim_free(p);
4009 	}
4010     }
4011     else if (*p == '&' || *p == '+')			/* option */
4012 	n = (get_option_var(&p, NULL, TRUE) == OK);
4013     else if (*p == '*')			/* internal or user defined function */
4014     {
4015 	++p;
4016 	p = trans_function_name(&p, FALSE, TRUE);
4017 	if (p != NULL)
4018 	{
4019 	    if (ASCII_ISUPPER(*p) || p[0] == K_SPECIAL)
4020 		n = (find_func(p) != NULL);
4021 	    else if (ASCII_ISLOWER(*p))
4022 		n = (find_internal_func(p) >= 0);
4023 	    vim_free(p);
4024 	}
4025     }
4026     else if (*p == ':')
4027     {
4028 	n = cmd_exists(p + 1);
4029     }
4030     else if (*p == '#')
4031     {
4032 #ifdef FEAT_AUTOCMD
4033 	name = p + 1;
4034 	p = vim_strchr(name, '#');
4035 	if (p != NULL)
4036 	    n = au_exists(name, p, p + 1);
4037 	else
4038 	    n = au_exists(name, name + STRLEN(name), NULL);
4039 #endif
4040     }
4041     else				/* internal variable */
4042     {
4043 #ifdef FEAT_MAGIC_BRACES
4044 	char_u	*expr_start;
4045 	char_u	*expr_end;
4046 	char_u  *temp_string = NULL;
4047 	char_u	*s;
4048 #endif
4049 	name = p;
4050 
4051 #ifdef FEAT_MAGIC_BRACES
4052 	/* Find the end of the name. */
4053 	s = find_name_end(name, &expr_start, &expr_end);
4054 	if (expr_start != NULL)
4055 	{
4056 	    temp_string = make_expanded_name(name, expr_start, expr_end, s);
4057 	    if (temp_string != NULL)
4058 	    {
4059 		len = STRLEN(temp_string);
4060 		name = temp_string;
4061 	    }
4062 	}
4063 #endif
4064 	if (len == 0)
4065 	    len = get_id_len(&p);
4066 	if (len != 0)
4067 	    n = (get_var_var(name, len, NULL) == OK);
4068 
4069 #ifdef FEAT_MAGIC_BRACES
4070 	vim_free(temp_string);
4071 #endif
4072     }
4073 
4074     retvar->var_val.var_number = n;
4075 }
4076 
4077 /*
4078  * "expand()" function
4079  */
4080     static void
4081 f_expand(argvars, retvar)
4082     VAR		argvars;
4083     VAR		retvar;
4084 {
4085     char_u	*s;
4086     int		len;
4087     char_u	*errormsg;
4088     int		flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
4089     expand_T	xpc;
4090 
4091     retvar->var_type = VAR_STRING;
4092     s = get_var_string(&argvars[0]);
4093     if (*s == '%' || *s == '#' || *s == '<')
4094     {
4095 	++emsg_off;
4096 	retvar->var_val.var_string = eval_vars(s, &len, NULL, &errormsg, s);
4097 	--emsg_off;
4098     }
4099     else
4100     {
4101 	/* When the optional second argument is non-zero, don't remove matches
4102 	 * for 'suffixes' and 'wildignore' */
4103 	if (argvars[1].var_type != VAR_UNKNOWN && get_var_number(&argvars[1]))
4104 	    flags |= WILD_KEEP_ALL;
4105 	ExpandInit(&xpc);
4106 	xpc.xp_context = EXPAND_FILES;
4107 	retvar->var_val.var_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL);
4108 	ExpandCleanup(&xpc);
4109     }
4110 }
4111 
4112 /*
4113  * "filereadable()" function
4114  */
4115     static void
4116 f_filereadable(argvars, retvar)
4117     VAR		argvars;
4118     VAR		retvar;
4119 {
4120     FILE	*fd;
4121     char_u	*p;
4122     int		n;
4123 
4124     p = get_var_string(&argvars[0]);
4125     if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL)
4126     {
4127 	n = TRUE;
4128 	fclose(fd);
4129     }
4130     else
4131 	n = FALSE;
4132 
4133     retvar->var_val.var_number = n;
4134 }
4135 
4136 /*
4137  * return 0 for not writable, 1 for writable file, 2 for a dir which we have
4138  * rights to write into.
4139  */
4140     static void
4141 f_filewritable(argvars, retvar)
4142     VAR		argvars;
4143     VAR		retvar;
4144 {
4145     char_u	*p;
4146     int		retval = 0;
4147 #if defined(UNIX) || defined(VMS)
4148     int		perm = 0;
4149 #endif
4150 
4151     p = get_var_string(&argvars[0]);
4152 #if defined(UNIX) || defined(VMS)
4153     perm = mch_getperm(p);
4154 #endif
4155 #ifndef MACOS_CLASSIC /* TODO: get either mch_writable or mch_access */
4156     if (
4157 # ifdef WIN3264
4158 	    mch_writable(p) &&
4159 # else
4160 # if defined(UNIX) || defined(VMS)
4161 	    (perm & 0222) &&
4162 #  endif
4163 # endif
4164 	    mch_access((char *)p, W_OK) == 0
4165        )
4166 #endif
4167     {
4168 	++retval;
4169 	if (mch_isdir(p))
4170 	    ++retval;
4171     }
4172     retvar->var_val.var_number = retval;
4173 }
4174 
4175 /*
4176  * "finddir({fname}[, {path}[, {count}]])" function
4177  */
4178     static void
4179 f_finddir(argvars, retvar)
4180     VAR		argvars;
4181     VAR		retvar;
4182 {
4183     f_findfilendir(argvars, retvar, TRUE);
4184 }
4185 
4186 /*
4187  * "findfile({fname}[, {path}[, {count}]])" function
4188  */
4189     static void
4190 f_findfile(argvars, retvar)
4191     VAR		argvars;
4192     VAR		retvar;
4193 {
4194     f_findfilendir(argvars, retvar, FALSE);
4195 }
4196 
4197     static void
4198 f_findfilendir(argvars, retvar, dir)
4199     VAR		argvars;
4200     VAR		retvar;
4201     int		dir;
4202 {
4203 #ifdef FEAT_SEARCHPATH
4204     char_u	*fname;
4205     char_u	*fresult = NULL;
4206     char_u	*path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
4207     char_u	*p;
4208     char_u	pathbuf[NUMBUFLEN];
4209     int		count = 1;
4210     int		first = TRUE;
4211 
4212     fname = get_var_string(&argvars[0]);
4213 
4214     if (argvars[1].var_type != VAR_UNKNOWN)
4215     {
4216 	p = get_var_string_buf(&argvars[1], pathbuf);
4217 	if (*p != NUL)
4218 	    path = p;
4219 
4220 	if (argvars[2].var_type != VAR_UNKNOWN)
4221 	    count = get_var_number(&argvars[2]);
4222     }
4223 
4224     do
4225     {
4226 	vim_free(fresult);
4227 	fresult = find_file_in_path_option(first ? fname : NULL,
4228 					    first ? (int)STRLEN(fname) : 0,
4229 					    0, first, path, dir, NULL);
4230 	first = FALSE;
4231     } while (--count > 0 && fresult != NULL);
4232 
4233     retvar->var_val.var_string = fresult;
4234 #else
4235     retvar->var_val.var_string = NULL;
4236 #endif
4237     retvar->var_type = VAR_STRING;
4238 }
4239 
4240 /*
4241  * "fnamemodify({fname}, {mods})" function
4242  */
4243     static void
4244 f_fnamemodify(argvars, retvar)
4245     VAR		argvars;
4246     VAR		retvar;
4247 {
4248     char_u	*fname;
4249     char_u	*mods;
4250     int		usedlen = 0;
4251     int		len;
4252     char_u	*fbuf = NULL;
4253     char_u	buf[NUMBUFLEN];
4254 
4255     fname = get_var_string(&argvars[0]);
4256     mods = get_var_string_buf(&argvars[1], buf);
4257     len = (int)STRLEN(fname);
4258 
4259     (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
4260 
4261     retvar->var_type = VAR_STRING;
4262     if (fname == NULL)
4263 	retvar->var_val.var_string = NULL;
4264     else
4265 	retvar->var_val.var_string = vim_strnsave(fname, len);
4266     vim_free(fbuf);
4267 }
4268 
4269 /*
4270  * "foldclosed()" function
4271  */
4272     static void
4273 f_foldclosed(argvars, retvar)
4274     VAR		argvars;
4275     VAR		retvar;
4276 {
4277     foldclosed_both(argvars, retvar, FALSE);
4278 }
4279 
4280 /*
4281  * "foldclosedend()" function
4282  */
4283     static void
4284 f_foldclosedend(argvars, retvar)
4285     VAR		argvars;
4286     VAR		retvar;
4287 {
4288     foldclosed_both(argvars, retvar, TRUE);
4289 }
4290 
4291 /*
4292  * "foldclosed()" function
4293  */
4294     static void
4295 foldclosed_both(argvars, retvar, end)
4296     VAR		argvars;
4297     VAR		retvar;
4298     int		end;
4299 {
4300 #ifdef FEAT_FOLDING
4301     linenr_T	lnum;
4302     linenr_T	first, last;
4303 
4304     lnum = get_var_lnum(argvars);
4305     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
4306     {
4307 	if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL))
4308 	{
4309 	    if (end)
4310 		retvar->var_val.var_number = (varnumber_T)last;
4311 	    else
4312 		retvar->var_val.var_number = (varnumber_T)first;
4313 	    return;
4314 	}
4315     }
4316 #endif
4317     retvar->var_val.var_number = -1;
4318 }
4319 
4320 /*
4321  * "foldlevel()" function
4322  */
4323     static void
4324 f_foldlevel(argvars, retvar)
4325     VAR		argvars;
4326     VAR		retvar;
4327 {
4328 #ifdef FEAT_FOLDING
4329     linenr_T	lnum;
4330 
4331     lnum = get_var_lnum(argvars);
4332     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
4333 	retvar->var_val.var_number = foldLevel(lnum);
4334     else
4335 #endif
4336 	retvar->var_val.var_number = 0;
4337 }
4338 
4339 /*
4340  * "foldtext()" function
4341  */
4342 /*ARGSUSED*/
4343     static void
4344 f_foldtext(argvars, retvar)
4345     VAR		argvars;
4346     VAR		retvar;
4347 {
4348 #ifdef FEAT_FOLDING
4349     linenr_T	lnum;
4350     char_u	*s;
4351     char_u	*r;
4352     int		len;
4353     char	*txt;
4354 #endif
4355 
4356     retvar->var_type = VAR_STRING;
4357     retvar->var_val.var_string = NULL;
4358 #ifdef FEAT_FOLDING
4359     if ((linenr_T)vimvars[VV_FOLDSTART].val > 0
4360 	    && (linenr_T)vimvars[VV_FOLDEND].val <= curbuf->b_ml.ml_line_count
4361 	    && vimvars[VV_FOLDDASHES].val != NULL)
4362     {
4363 	/* Find first non-empty line in the fold. */
4364 	lnum = (linenr_T)vimvars[VV_FOLDSTART].val;
4365 	while (lnum < (linenr_T)vimvars[VV_FOLDEND].val)
4366 	{
4367 	    if (!linewhite(lnum))
4368 		break;
4369 	    ++lnum;
4370 	}
4371 
4372 	/* Find interesting text in this line. */
4373 	s = skipwhite(ml_get(lnum));
4374 	/* skip C comment-start */
4375 	if (s[0] == '/' && (s[1] == '*' || s[1] == '/'))
4376 	    s = skipwhite(s + 2);
4377 	txt = _("+-%s%3ld lines: ");
4378 	r = alloc((unsigned)(STRLEN(txt)
4379 		    + STRLEN(vimvars[VV_FOLDDASHES].val)    /* for %s */
4380 		    + 20				    /* for %3ld */
4381 		    + STRLEN(s)));			    /* concatenated */
4382 	if (r != NULL)
4383 	{
4384 	    sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].val,
4385 		    (long)((linenr_T)vimvars[VV_FOLDEND].val
4386 				   - (linenr_T)vimvars[VV_FOLDSTART].val + 1));
4387 	    len = (int)STRLEN(r);
4388 	    STRCAT(r, s);
4389 	    /* remove 'foldmarker' and 'commentstring' */
4390 	    foldtext_cleanup(r + len);
4391 	    retvar->var_val.var_string = r;
4392 	}
4393     }
4394 #endif
4395 }
4396 
4397 /*
4398  * "foreground()" function
4399  */
4400 /*ARGSUSED*/
4401     static void
4402 f_foreground(argvars, retvar)
4403     VAR		argvars;
4404     VAR		retvar;
4405 {
4406     retvar->var_val.var_number = 0;
4407 #ifdef FEAT_GUI
4408     if (gui.in_use)
4409 	gui_mch_set_foreground();
4410 #else
4411 # ifdef WIN32
4412     win32_set_foreground();
4413 # endif
4414 #endif
4415 }
4416 
4417 /*
4418  * "getchar()" function
4419  */
4420     static void
4421 f_getchar(argvars, retvar)
4422     VAR		argvars;
4423     VAR		retvar;
4424 {
4425     varnumber_T		n;
4426 
4427     ++no_mapping;
4428     ++allow_keys;
4429     if (argvars[0].var_type == VAR_UNKNOWN)
4430 	/* getchar(): blocking wait. */
4431 	n = safe_vgetc();
4432     else if (get_var_number(&argvars[0]) == 1)
4433 	/* getchar(1): only check if char avail */
4434 	n = vpeekc();
4435     else if (vpeekc() == NUL)
4436 	/* getchar(0) and no char avail: return zero */
4437 	n = 0;
4438     else
4439 	/* getchar(0) and char avail: return char */
4440 	n = safe_vgetc();
4441     --no_mapping;
4442     --allow_keys;
4443 
4444     retvar->var_val.var_number = n;
4445     if (IS_SPECIAL(n) || mod_mask != 0)
4446     {
4447 	char_u		temp[10];   /* modifier: 3, mbyte-char: 6, NUL: 1 */
4448 	int		i = 0;
4449 
4450 	/* Turn a special key into three bytes, plus modifier. */
4451 	if (mod_mask != 0)
4452 	{
4453 	    temp[i++] = K_SPECIAL;
4454 	    temp[i++] = KS_MODIFIER;
4455 	    temp[i++] = mod_mask;
4456 	}
4457 	if (IS_SPECIAL(n))
4458 	{
4459 	    temp[i++] = K_SPECIAL;
4460 	    temp[i++] = K_SECOND(n);
4461 	    temp[i++] = K_THIRD(n);
4462 	}
4463 #ifdef FEAT_MBYTE
4464 	else if (has_mbyte)
4465 	    i += (*mb_char2bytes)(n, temp + i);
4466 #endif
4467 	else
4468 	    temp[i++] = n;
4469 	temp[i++] = NUL;
4470 	retvar->var_type = VAR_STRING;
4471 	retvar->var_val.var_string = vim_strsave(temp);
4472     }
4473 }
4474 
4475 /*
4476  * "getcharmod()" function
4477  */
4478 /*ARGSUSED*/
4479     static void
4480 f_getcharmod(argvars, retvar)
4481     VAR		argvars;
4482     VAR		retvar;
4483 {
4484     retvar->var_val.var_number = mod_mask;
4485 }
4486 
4487 /*
4488  * "getcmdline()" function
4489  */
4490 /*ARGSUSED*/
4491     static void
4492 f_getcmdline(argvars, retvar)
4493     VAR		argvars;
4494     VAR		retvar;
4495 {
4496     retvar->var_type = VAR_STRING;
4497     retvar->var_val.var_string = get_cmdline_str();
4498 }
4499 
4500 /*
4501  * "getcmdpos()" function
4502  */
4503 /*ARGSUSED*/
4504     static void
4505 f_getcmdpos(argvars, retvar)
4506     VAR		argvars;
4507     VAR		retvar;
4508 {
4509     retvar->var_val.var_number = get_cmdline_pos() + 1;
4510 }
4511 
4512 /*
4513  * "getbufvar()" function
4514  */
4515     static void
4516 f_getbufvar(argvars, retvar)
4517     VAR		argvars;
4518     VAR		retvar;
4519 {
4520     buf_T	*buf;
4521     buf_T	*save_curbuf;
4522     char_u	*varname;
4523     VAR		v;
4524 
4525     ++emsg_off;
4526     buf = get_buf_var(&argvars[0]);
4527     varname = get_var_string(&argvars[1]);
4528 
4529     retvar->var_type = VAR_STRING;
4530     retvar->var_val.var_string = NULL;
4531 
4532     if (buf != NULL && varname != NULL)
4533     {
4534 	if (*varname == '&')	/* buffer-local-option */
4535 	{
4536 	    /* set curbuf to be our buf, temporarily */
4537 	    save_curbuf = curbuf;
4538 	    curbuf = buf;
4539 
4540 	    get_option_var(&varname, retvar, TRUE);
4541 
4542 	    /* restore previous notion of curbuf */
4543 	    curbuf = save_curbuf;
4544 	}
4545 	else
4546 	{
4547 	    /* look up the variable */
4548 	    v = find_var_in_ga(&buf->b_vars, varname);
4549 	    if (v != NULL)
4550 		copy_var(v, retvar);
4551 	}
4552     }
4553 
4554     --emsg_off;
4555 }
4556 
4557 /*
4558  * "getcwd()" function
4559  */
4560 /*ARGSUSED*/
4561     static void
4562 f_getcwd(argvars, retvar)
4563     VAR		argvars;
4564     VAR		retvar;
4565 {
4566     char_u	cwd[MAXPATHL];
4567 
4568     retvar->var_type = VAR_STRING;
4569     if (mch_dirname(cwd, MAXPATHL) == FAIL)
4570 	retvar->var_val.var_string = NULL;
4571     else
4572     {
4573 	retvar->var_val.var_string = vim_strsave(cwd);
4574 #ifdef BACKSLASH_IN_FILENAME
4575 	slash_adjust(retvar->var_val.var_string);
4576 #endif
4577     }
4578 }
4579 
4580 /*
4581  * "getfsize({fname})" function
4582  */
4583     static void
4584 f_getfsize(argvars, retvar)
4585     VAR		argvars;
4586     VAR		retvar;
4587 {
4588     char_u	*fname;
4589     struct stat	st;
4590 
4591     fname = get_var_string(&argvars[0]);
4592 
4593     retvar->var_type = VAR_NUMBER;
4594 
4595     if (mch_stat((char *)fname, &st) >= 0)
4596     {
4597 	if (mch_isdir(fname))
4598 	    retvar->var_val.var_number = 0;
4599 	else
4600 	    retvar->var_val.var_number = (varnumber_T)st.st_size;
4601     }
4602     else
4603 	  retvar->var_val.var_number = -1;
4604 }
4605 
4606 /*
4607  * "getftime({fname})" function
4608  */
4609     static void
4610 f_getftime(argvars, retvar)
4611     VAR		argvars;
4612     VAR		retvar;
4613 {
4614     char_u	*fname;
4615     struct stat	st;
4616 
4617     fname = get_var_string(&argvars[0]);
4618 
4619     if (mch_stat((char *)fname, &st) >= 0)
4620 	retvar->var_val.var_number = (varnumber_T)st.st_mtime;
4621     else
4622 	retvar->var_val.var_number = -1;
4623 }
4624 
4625 /*
4626  * "getreg()" function
4627  */
4628     static void
4629 f_getreg(argvars, retvar)
4630     VAR		argvars;
4631     VAR		retvar;
4632 {
4633     char_u	*strregname;
4634     int		regname;
4635 
4636     if (argvars[0].var_type != VAR_UNKNOWN)
4637 	strregname = get_var_string(&argvars[0]);
4638     else
4639 	strregname = vimvars[VV_REG].val;
4640     regname = (strregname == NULL ? '"' : *strregname);
4641     if (regname == 0)
4642 	regname = '"';
4643 
4644     retvar->var_type = VAR_STRING;
4645     retvar->var_val.var_string = get_reg_contents(regname, TRUE);
4646 }
4647 
4648 /*
4649  * "getregtype()" function
4650  */
4651     static void
4652 f_getregtype(argvars, retvar)
4653     VAR		argvars;
4654     VAR		retvar;
4655 {
4656     char_u	*strregname;
4657     int		regname;
4658     char_u	buf[NUMBUFLEN + 2];
4659     long	reglen = 0;
4660 
4661     if (argvars[0].var_type != VAR_UNKNOWN)
4662 	strregname = get_var_string(&argvars[0]);
4663     else
4664 	/* Default to v:register */
4665 	strregname = vimvars[VV_REG].val;
4666 
4667     regname = (strregname == NULL ? '"' : *strregname);
4668     if (regname == 0)
4669 	regname = '"';
4670 
4671     buf[0] = NUL;
4672     buf[1] = NUL;
4673     switch (get_reg_type(regname, &reglen))
4674     {
4675 	case MLINE: buf[0] = 'V'; break;
4676 	case MCHAR: buf[0] = 'v'; break;
4677 #ifdef FEAT_VISUAL
4678 	case MBLOCK:
4679 		buf[0] = Ctrl_V;
4680 		sprintf((char *)buf + 1, "%ld", reglen + 1);
4681 		break;
4682 #endif
4683     }
4684     retvar->var_type = VAR_STRING;
4685     retvar->var_val.var_string = vim_strsave(buf);
4686 }
4687 
4688 /*
4689  * "getline(lnum)" function
4690  */
4691     static void
4692 f_getline(argvars, retvar)
4693     VAR		argvars;
4694     VAR		retvar;
4695 {
4696     linenr_T	lnum;
4697     char_u	*p;
4698 
4699     lnum = get_var_lnum(argvars);
4700 
4701     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
4702 	p = ml_get(lnum);
4703     else
4704 	p = (char_u *)"";
4705 
4706     retvar->var_type = VAR_STRING;
4707     retvar->var_val.var_string = vim_strsave(p);
4708 }
4709 
4710 /*
4711  * "getwinposx()" function
4712  */
4713 /*ARGSUSED*/
4714     static void
4715 f_getwinposx(argvars, retvar)
4716     VAR		argvars;
4717     VAR		retvar;
4718 {
4719     retvar->var_val.var_number = -1;
4720 #ifdef FEAT_GUI
4721     if (gui.in_use)
4722     {
4723 	int	    x, y;
4724 
4725 	if (gui_mch_get_winpos(&x, &y) == OK)
4726 	    retvar->var_val.var_number = x;
4727     }
4728 #endif
4729 }
4730 
4731 /*
4732  * "getwinposy()" function
4733  */
4734 /*ARGSUSED*/
4735     static void
4736 f_getwinposy(argvars, retvar)
4737     VAR		argvars;
4738     VAR		retvar;
4739 {
4740     retvar->var_val.var_number = -1;
4741 #ifdef FEAT_GUI
4742     if (gui.in_use)
4743     {
4744 	int	    x, y;
4745 
4746 	if (gui_mch_get_winpos(&x, &y) == OK)
4747 	    retvar->var_val.var_number = y;
4748     }
4749 #endif
4750 }
4751 
4752 /*
4753  * "getwinvar()" function
4754  */
4755     static void
4756 f_getwinvar(argvars, retvar)
4757     VAR		argvars;
4758     VAR		retvar;
4759 {
4760     win_T	*win, *oldcurwin;
4761     char_u	*varname;
4762     VAR		v;
4763 
4764     ++emsg_off;
4765     win = find_win_by_nr(&argvars[0]);
4766     varname = get_var_string(&argvars[1]);
4767 
4768     retvar->var_type = VAR_STRING;
4769     retvar->var_val.var_string = NULL;
4770 
4771     if (win != NULL && varname != NULL)
4772     {
4773 	if (*varname == '&')	/* window-local-option */
4774 	{
4775 	    /* set curwin to be our win, temporarily */
4776 	    oldcurwin = curwin;
4777 	    curwin = win;
4778 
4779 	    get_option_var(&varname, retvar , 1);
4780 
4781 	    /* restore previous notion of curwin */
4782 	    curwin = oldcurwin;
4783 	}
4784 	else
4785 	{
4786 	    /* look up the variable */
4787 	    v = find_var_in_ga(&win->w_vars, varname);
4788 	    if (v != NULL)
4789 		copy_var(v, retvar);
4790 	}
4791     }
4792 
4793     --emsg_off;
4794 }
4795 
4796 /*
4797  * "glob()" function
4798  */
4799     static void
4800 f_glob(argvars, retvar)
4801     VAR		argvars;
4802     VAR		retvar;
4803 {
4804     expand_T	xpc;
4805 
4806     ExpandInit(&xpc);
4807     xpc.xp_context = EXPAND_FILES;
4808     retvar->var_type = VAR_STRING;
4809     retvar->var_val.var_string = ExpandOne(&xpc, get_var_string(&argvars[0]),
4810 				     NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL);
4811     ExpandCleanup(&xpc);
4812 }
4813 
4814 /*
4815  * "globpath()" function
4816  */
4817     static void
4818 f_globpath(argvars, retvar)
4819     VAR		argvars;
4820     VAR		retvar;
4821 {
4822     char_u	buf1[NUMBUFLEN];
4823 
4824     retvar->var_type = VAR_STRING;
4825     retvar->var_val.var_string = globpath(get_var_string(&argvars[0]),
4826 				       get_var_string_buf(&argvars[1], buf1));
4827 }
4828 
4829 /*
4830  * "has()" function
4831  */
4832     static void
4833 f_has(argvars, retvar)
4834     VAR		argvars;
4835     VAR		retvar;
4836 {
4837     int		i;
4838     char_u	*name;
4839     int		n = FALSE;
4840     static char	*(has_list[]) =
4841     {
4842 #ifdef AMIGA
4843 	"amiga",
4844 # ifdef FEAT_ARP
4845 	"arp",
4846 # endif
4847 #endif
4848 #ifdef __BEOS__
4849 	"beos",
4850 #endif
4851 #ifdef MSDOS
4852 # ifdef DJGPP
4853 	"dos32",
4854 # else
4855 	"dos16",
4856 # endif
4857 #endif
4858 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */
4859 	"mac",
4860 #endif
4861 #if defined(MACOS_X_UNIX)
4862 	"macunix",
4863 #endif
4864 #ifdef OS2
4865 	"os2",
4866 #endif
4867 #ifdef __QNX__
4868 	"qnx",
4869 #endif
4870 #ifdef RISCOS
4871 	"riscos",
4872 #endif
4873 #ifdef UNIX
4874 	"unix",
4875 #endif
4876 #ifdef VMS
4877 	"vms",
4878 #endif
4879 #ifdef WIN16
4880 	"win16",
4881 #endif
4882 #ifdef WIN32
4883 	"win32",
4884 #endif
4885 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__))
4886 	"win32unix",
4887 #endif
4888 #ifdef WIN64
4889 	"win64",
4890 #endif
4891 #ifdef EBCDIC
4892 	"ebcdic",
4893 #endif
4894 #ifndef CASE_INSENSITIVE_FILENAME
4895 	"fname_case",
4896 #endif
4897 #ifdef FEAT_ARABIC
4898 	"arabic",
4899 #endif
4900 #ifdef FEAT_AUTOCMD
4901 	"autocmd",
4902 #endif
4903 #ifdef FEAT_BEVAL
4904 	"balloon_eval",
4905 #endif
4906 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
4907 	"builtin_terms",
4908 # ifdef ALL_BUILTIN_TCAPS
4909 	"all_builtin_terms",
4910 # endif
4911 #endif
4912 #ifdef FEAT_BYTEOFF
4913 	"byte_offset",
4914 #endif
4915 #ifdef FEAT_CINDENT
4916 	"cindent",
4917 #endif
4918 #ifdef FEAT_CLIENTSERVER
4919 	"clientserver",
4920 #endif
4921 #ifdef FEAT_CLIPBOARD
4922 	"clipboard",
4923 #endif
4924 #ifdef FEAT_CMDL_COMPL
4925 	"cmdline_compl",
4926 #endif
4927 #ifdef FEAT_CMDHIST
4928 	"cmdline_hist",
4929 #endif
4930 #ifdef FEAT_COMMENTS
4931 	"comments",
4932 #endif
4933 #ifdef FEAT_CRYPT
4934 	"cryptv",
4935 #endif
4936 #ifdef FEAT_CSCOPE
4937 	"cscope",
4938 #endif
4939 #ifdef DEBUG
4940 	"debug",
4941 #endif
4942 #ifdef FEAT_CON_DIALOG
4943 	"dialog_con",
4944 #endif
4945 #ifdef FEAT_GUI_DIALOG
4946 	"dialog_gui",
4947 #endif
4948 #ifdef FEAT_DIFF
4949 	"diff",
4950 #endif
4951 #ifdef FEAT_DIGRAPHS
4952 	"digraphs",
4953 #endif
4954 #ifdef FEAT_DND
4955 	"dnd",
4956 #endif
4957 #ifdef FEAT_EMACS_TAGS
4958 	"emacs_tags",
4959 #endif
4960 	"eval",	    /* always present, of course! */
4961 #ifdef FEAT_EX_EXTRA
4962 	"ex_extra",
4963 #endif
4964 #ifdef FEAT_SEARCH_EXTRA
4965 	"extra_search",
4966 #endif
4967 #ifdef FEAT_FKMAP
4968 	"farsi",
4969 #endif
4970 #ifdef FEAT_SEARCHPATH
4971 	"file_in_path",
4972 #endif
4973 #ifdef FEAT_FIND_ID
4974 	"find_in_path",
4975 #endif
4976 #ifdef FEAT_FOLDING
4977 	"folding",
4978 #endif
4979 #ifdef FEAT_FOOTER
4980 	"footer",
4981 #endif
4982 #if !defined(USE_SYSTEM) && defined(UNIX)
4983 	"fork",
4984 #endif
4985 #ifdef FEAT_GETTEXT
4986 	"gettext",
4987 #endif
4988 #ifdef FEAT_GUI
4989 	"gui",
4990 #endif
4991 #ifdef FEAT_GUI_ATHENA
4992 # ifdef FEAT_GUI_NEXTAW
4993 	"gui_neXtaw",
4994 # else
4995 	"gui_athena",
4996 # endif
4997 #endif
4998 #ifdef FEAT_GUI_BEOS
4999 	"gui_beos",
5000 #endif
5001 #ifdef FEAT_GUI_KDE
5002 	"gui_kde",
5003 #endif
5004 #ifdef FEAT_GUI_GTK
5005 	"gui_gtk",
5006 # ifdef HAVE_GTK2
5007 	"gui_gtk2",
5008 # endif
5009 #endif
5010 #ifdef FEAT_GUI_MAC
5011 	"gui_mac",
5012 #endif
5013 #ifdef FEAT_GUI_MOTIF
5014 	"gui_motif",
5015 #endif
5016 #ifdef FEAT_GUI_PHOTON
5017 	"gui_photon",
5018 #endif
5019 #ifdef FEAT_GUI_W16
5020 	"gui_win16",
5021 #endif
5022 #ifdef FEAT_GUI_W32
5023 	"gui_win32",
5024 #endif
5025 #ifdef FEAT_HANGULIN
5026 	"hangul_input",
5027 #endif
5028 #if defined(HAVE_ICONV_H) && defined(USE_ICONV)
5029 	"iconv",
5030 #endif
5031 #ifdef FEAT_INS_EXPAND
5032 	"insert_expand",
5033 #endif
5034 #ifdef FEAT_JUMPLIST
5035 	"jumplist",
5036 #endif
5037 #ifdef FEAT_KEYMAP
5038 	"keymap",
5039 #endif
5040 #ifdef FEAT_LANGMAP
5041 	"langmap",
5042 #endif
5043 #ifdef FEAT_LIBCALL
5044 	"libcall",
5045 #endif
5046 #ifdef FEAT_LINEBREAK
5047 	"linebreak",
5048 #endif
5049 #ifdef FEAT_LISP
5050 	"lispindent",
5051 #endif
5052 #ifdef FEAT_LISTCMDS
5053 	"listcmds",
5054 #endif
5055 #ifdef FEAT_LOCALMAP
5056 	"localmap",
5057 #endif
5058 #ifdef FEAT_MENU
5059 	"menu",
5060 #endif
5061 #ifdef FEAT_SESSION
5062 	"mksession",
5063 #endif
5064 #ifdef FEAT_MODIFY_FNAME
5065 	"modify_fname",
5066 #endif
5067 #ifdef FEAT_MOUSE
5068 	"mouse",
5069 #endif
5070 #ifdef FEAT_MOUSESHAPE
5071 	"mouseshape",
5072 #endif
5073 #if defined(UNIX) || defined(VMS)
5074 # ifdef FEAT_MOUSE_DEC
5075 	"mouse_dec",
5076 # endif
5077 # ifdef FEAT_MOUSE_GPM
5078 	"mouse_gpm",
5079 # endif
5080 # ifdef FEAT_MOUSE_JSB
5081 	"mouse_jsbterm",
5082 # endif
5083 # ifdef FEAT_MOUSE_NET
5084 	"mouse_netterm",
5085 # endif
5086 # ifdef FEAT_MOUSE_PTERM
5087 	"mouse_pterm",
5088 # endif
5089 # ifdef FEAT_MOUSE_XTERM
5090 	"mouse_xterm",
5091 # endif
5092 #endif
5093 #ifdef FEAT_MBYTE
5094 	"multi_byte",
5095 #endif
5096 #ifdef FEAT_MBYTE_IME
5097 	"multi_byte_ime",
5098 #endif
5099 #ifdef FEAT_MULTI_LANG
5100 	"multi_lang",
5101 #endif
5102 #ifdef FEAT_MZSCHEME
5103 	"mzscheme",
5104 #endif
5105 #ifdef FEAT_OLE
5106 	"ole",
5107 #endif
5108 #ifdef FEAT_OSFILETYPE
5109 	"osfiletype",
5110 #endif
5111 #ifdef FEAT_PATH_EXTRA
5112 	"path_extra",
5113 #endif
5114 #ifdef FEAT_PERL
5115 #ifndef DYNAMIC_PERL
5116 	"perl",
5117 #endif
5118 #endif
5119 #ifdef FEAT_PYTHON
5120 #ifndef DYNAMIC_PYTHON
5121 	"python",
5122 #endif
5123 #endif
5124 #ifdef FEAT_POSTSCRIPT
5125 	"postscript",
5126 #endif
5127 #ifdef FEAT_PRINTER
5128 	"printer",
5129 #endif
5130 #ifdef FEAT_QUICKFIX
5131 	"quickfix",
5132 #endif
5133 #ifdef FEAT_RIGHTLEFT
5134 	"rightleft",
5135 #endif
5136 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY)
5137 	"ruby",
5138 #endif
5139 #ifdef FEAT_SCROLLBIND
5140 	"scrollbind",
5141 #endif
5142 #ifdef FEAT_CMDL_INFO
5143 	"showcmd",
5144 	"cmdline_info",
5145 #endif
5146 #ifdef FEAT_SIGNS
5147 	"signs",
5148 #endif
5149 #ifdef FEAT_SMARTINDENT
5150 	"smartindent",
5151 #endif
5152 #ifdef FEAT_SNIFF
5153 	"sniff",
5154 #endif
5155 #ifdef FEAT_STL_OPT
5156 	"statusline",
5157 #endif
5158 #ifdef FEAT_SUN_WORKSHOP
5159 	"sun_workshop",
5160 #endif
5161 #ifdef FEAT_NETBEANS_INTG
5162 	"netbeans_intg",
5163 #endif
5164 #ifdef FEAT_SYN_HL
5165 	"syntax",
5166 #endif
5167 #if defined(USE_SYSTEM) || !defined(UNIX)
5168 	"system",
5169 #endif
5170 #ifdef FEAT_TAG_BINS
5171 	"tag_binary",
5172 #endif
5173 #ifdef FEAT_TAG_OLDSTATIC
5174 	"tag_old_static",
5175 #endif
5176 #ifdef FEAT_TAG_ANYWHITE
5177 	"tag_any_white",
5178 #endif
5179 #ifdef FEAT_TCL
5180 # ifndef DYNAMIC_TCL
5181 	"tcl",
5182 # endif
5183 #endif
5184 #ifdef TERMINFO
5185 	"terminfo",
5186 #endif
5187 #ifdef FEAT_TERMRESPONSE
5188 	"termresponse",
5189 #endif
5190 #ifdef FEAT_TEXTOBJ
5191 	"textobjects",
5192 #endif
5193 #ifdef HAVE_TGETENT
5194 	"tgetent",
5195 #endif
5196 #ifdef FEAT_TITLE
5197 	"title",
5198 #endif
5199 #ifdef FEAT_TOOLBAR
5200 	"toolbar",
5201 #endif
5202 #ifdef FEAT_USR_CMDS
5203 	"user-commands",    /* was accidentally included in 5.4 */
5204 	"user_commands",
5205 #endif
5206 #ifdef FEAT_VIMINFO
5207 	"viminfo",
5208 #endif
5209 #ifdef FEAT_VERTSPLIT
5210 	"vertsplit",
5211 #endif
5212 #ifdef FEAT_VIRTUALEDIT
5213 	"virtualedit",
5214 #endif
5215 #ifdef FEAT_VISUAL
5216 	"visual",
5217 #endif
5218 #ifdef FEAT_VISUALEXTRA
5219 	"visualextra",
5220 #endif
5221 #ifdef FEAT_VREPLACE
5222 	"vreplace",
5223 #endif
5224 #ifdef FEAT_WILDIGN
5225 	"wildignore",
5226 #endif
5227 #ifdef FEAT_WILDMENU
5228 	"wildmenu",
5229 #endif
5230 #ifdef FEAT_WINDOWS
5231 	"windows",
5232 #endif
5233 #ifdef FEAT_WAK
5234 	"winaltkeys",
5235 #endif
5236 #ifdef FEAT_WRITEBACKUP
5237 	"writebackup",
5238 #endif
5239 #ifdef FEAT_XIM
5240 	"xim",
5241 #endif
5242 #ifdef FEAT_XFONTSET
5243 	"xfontset",
5244 #endif
5245 #ifdef USE_XSMP
5246 	"xsmp",
5247 #endif
5248 #ifdef USE_XSMP_INTERACT
5249 	"xsmp_interact",
5250 #endif
5251 #ifdef FEAT_XCLIPBOARD
5252 	"xterm_clipboard",
5253 #endif
5254 #ifdef FEAT_XTERM_SAVE
5255 	"xterm_save",
5256 #endif
5257 #if defined(UNIX) && defined(FEAT_X11)
5258 	"X11",
5259 #endif
5260 	NULL
5261     };
5262 
5263     name = get_var_string(&argvars[0]);
5264     for (i = 0; has_list[i] != NULL; ++i)
5265 	if (STRICMP(name, has_list[i]) == 0)
5266 	{
5267 	    n = TRUE;
5268 	    break;
5269 	}
5270 
5271     if (n == FALSE)
5272     {
5273 	if (STRNICMP(name, "patch", 5) == 0)
5274 	    n = has_patch(atoi((char *)name + 5));
5275 	else if (STRICMP(name, "vim_starting") == 0)
5276 	    n = (starting != 0);
5277 #ifdef DYNAMIC_TCL
5278 	else if (STRICMP(name, "tcl") == 0)
5279 	    n = tcl_enabled(FALSE);
5280 #endif
5281 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
5282 	else if (STRICMP(name, "iconv") == 0)
5283 	    n = iconv_enabled(FALSE);
5284 #endif
5285 #ifdef DYNAMIC_RUBY
5286 	else if (STRICMP(name, "ruby") == 0)
5287 	    n = ruby_enabled(FALSE);
5288 #endif
5289 #ifdef DYNAMIC_PYTHON
5290 	else if (STRICMP(name, "python") == 0)
5291 	    n = python_enabled(FALSE);
5292 #endif
5293 #ifdef DYNAMIC_PERL
5294 	else if (STRICMP(name, "perl") == 0)
5295 	    n = perl_enabled(FALSE);
5296 #endif
5297 #ifdef FEAT_GUI
5298 	else if (STRICMP(name, "gui_running") == 0)
5299 	    n = (gui.in_use || gui.starting);
5300 # ifdef FEAT_GUI_W32
5301 	else if (STRICMP(name, "gui_win32s") == 0)
5302 	    n = gui_is_win32s();
5303 # endif
5304 # ifdef FEAT_BROWSE
5305 	else if (STRICMP(name, "browse") == 0)
5306 	    n = gui.in_use;	/* gui_mch_browse() works when GUI is running */
5307 # endif
5308 #endif
5309 #ifdef FEAT_SYN_HL
5310 	else if (STRICMP(name, "syntax_items") == 0)
5311 	    n = syntax_present(curbuf);
5312 #endif
5313 #if defined(WIN3264)
5314 	else if (STRICMP(name, "win95") == 0)
5315 	    n = mch_windows95();
5316 #endif
5317     }
5318 
5319     retvar->var_val.var_number = n;
5320 }
5321 
5322 /*
5323  * "hasmapto()" function
5324  */
5325     static void
5326 f_hasmapto(argvars, retvar)
5327     VAR		argvars;
5328     VAR		retvar;
5329 {
5330     char_u	*name;
5331     char_u	*mode;
5332     char_u	buf[NUMBUFLEN];
5333 
5334     name = get_var_string(&argvars[0]);
5335     if (argvars[1].var_type == VAR_UNKNOWN)
5336 	mode = (char_u *)"nvo";
5337     else
5338 	mode = get_var_string_buf(&argvars[1], buf);
5339 
5340     if (map_to_exists(name, mode))
5341 	retvar->var_val.var_number = TRUE;
5342     else
5343 	retvar->var_val.var_number = FALSE;
5344 }
5345 
5346 /*
5347  * "histadd()" function
5348  */
5349 /*ARGSUSED*/
5350     static void
5351 f_histadd(argvars, retvar)
5352     VAR		argvars;
5353     VAR		retvar;
5354 {
5355 #ifdef FEAT_CMDHIST
5356     int		histype;
5357     char_u	*str;
5358     char_u	buf[NUMBUFLEN];
5359 #endif
5360 
5361     retvar->var_val.var_number = FALSE;
5362     if (check_restricted() || check_secure())
5363 	return;
5364 #ifdef FEAT_CMDHIST
5365     histype = get_histtype(get_var_string(&argvars[0]));
5366     if (histype >= 0)
5367     {
5368 	str = get_var_string_buf(&argvars[1], buf);
5369 	if (*str != NUL)
5370 	{
5371 	    add_to_history(histype, str, FALSE, NUL);
5372 	    retvar->var_val.var_number = TRUE;
5373 	    return;
5374 	}
5375     }
5376 #endif
5377 }
5378 
5379 /*
5380  * "histdel()" function
5381  */
5382 /*ARGSUSED*/
5383     static void
5384 f_histdel(argvars, retvar)
5385     VAR		argvars;
5386     VAR		retvar;
5387 {
5388 #ifdef FEAT_CMDHIST
5389     int		n;
5390     char_u	buf[NUMBUFLEN];
5391 
5392     if (argvars[1].var_type == VAR_UNKNOWN)
5393 	/* only one argument: clear entire history */
5394 	n = clr_history(get_histtype(get_var_string(&argvars[0])));
5395     else if (argvars[1].var_type == VAR_NUMBER)
5396 	/* index given: remove that entry */
5397 	n = del_history_idx(get_histtype(get_var_string(&argvars[0])),
5398 					    (int)get_var_number(&argvars[1]));
5399     else
5400 	/* string given: remove all matching entries */
5401 	n = del_history_entry(get_histtype(get_var_string(&argvars[0])),
5402 					get_var_string_buf(&argvars[1], buf));
5403     retvar->var_val.var_number = n;
5404 #else
5405     retvar->var_val.var_number = 0;
5406 #endif
5407 }
5408 
5409 /*
5410  * "histget()" function
5411  */
5412 /*ARGSUSED*/
5413     static void
5414 f_histget(argvars, retvar)
5415     VAR		argvars;
5416     VAR		retvar;
5417 {
5418 #ifdef FEAT_CMDHIST
5419     int		type;
5420     int		idx;
5421 
5422     type = get_histtype(get_var_string(&argvars[0]));
5423     if (argvars[1].var_type == VAR_UNKNOWN)
5424 	idx = get_history_idx(type);
5425     else
5426 	idx = (int)get_var_number(&argvars[1]);
5427     retvar->var_val.var_string = vim_strsave(get_history_entry(type, idx));
5428 #else
5429     retvar->var_val.var_string = NULL;
5430 #endif
5431     retvar->var_type = VAR_STRING;
5432 }
5433 
5434 /*
5435  * "histnr()" function
5436  */
5437 /*ARGSUSED*/
5438     static void
5439 f_histnr(argvars, retvar)
5440     VAR		argvars;
5441     VAR		retvar;
5442 {
5443     int		i;
5444 
5445 #ifdef FEAT_CMDHIST
5446     i = get_histtype(get_var_string(&argvars[0]));
5447     if (i >= HIST_CMD && i < HIST_COUNT)
5448 	i = get_history_idx(i);
5449     else
5450 #endif
5451 	i = -1;
5452     retvar->var_val.var_number = i;
5453 }
5454 
5455 /*
5456  * "highlight_exists()" function
5457  */
5458     static void
5459 f_hlexists(argvars, retvar)
5460     VAR		argvars;
5461     VAR		retvar;
5462 {
5463     retvar->var_val.var_number = highlight_exists(get_var_string(&argvars[0]));
5464 }
5465 
5466 /*
5467  * "highlightID(name)" function
5468  */
5469     static void
5470 f_hlID(argvars, retvar)
5471     VAR		argvars;
5472     VAR		retvar;
5473 {
5474     retvar->var_val.var_number = syn_name2id(get_var_string(&argvars[0]));
5475 }
5476 
5477 /*
5478  * "hostname()" function
5479  */
5480 /*ARGSUSED*/
5481     static void
5482 f_hostname(argvars, retvar)
5483     VAR		argvars;
5484     VAR		retvar;
5485 {
5486     char_u hostname[256];
5487 
5488     mch_get_host_name(hostname, 256);
5489     retvar->var_type = VAR_STRING;
5490     retvar->var_val.var_string = vim_strsave(hostname);
5491 }
5492 
5493 /*
5494  * iconv() function
5495  */
5496 /*ARGSUSED*/
5497     static void
5498 f_iconv(argvars, retvar)
5499     VAR		argvars;
5500     VAR		retvar;
5501 {
5502 #ifdef FEAT_MBYTE
5503     char_u	buf1[NUMBUFLEN];
5504     char_u	buf2[NUMBUFLEN];
5505     char_u	*from, *to, *str;
5506     vimconv_T	vimconv;
5507 #endif
5508 
5509     retvar->var_type = VAR_STRING;
5510     retvar->var_val.var_string = NULL;
5511 
5512 #ifdef FEAT_MBYTE
5513     str = get_var_string(&argvars[0]);
5514     from = enc_canonize(enc_skip(get_var_string_buf(&argvars[1], buf1)));
5515     to = enc_canonize(enc_skip(get_var_string_buf(&argvars[2], buf2)));
5516     vimconv.vc_type = CONV_NONE;
5517     convert_setup(&vimconv, from, to);
5518 
5519     /* If the encodings are equal, no conversion needed. */
5520     if (vimconv.vc_type == CONV_NONE)
5521 	retvar->var_val.var_string = vim_strsave(str);
5522     else
5523 	retvar->var_val.var_string = string_convert(&vimconv, str, NULL);
5524 
5525     convert_setup(&vimconv, NULL, NULL);
5526     vim_free(from);
5527     vim_free(to);
5528 #endif
5529 }
5530 
5531 /*
5532  * "indent()" function
5533  */
5534     static void
5535 f_indent(argvars, retvar)
5536     VAR		argvars;
5537     VAR		retvar;
5538 {
5539     linenr_T	lnum;
5540 
5541     lnum = get_var_lnum(argvars);
5542     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
5543 	retvar->var_val.var_number = get_indent_lnum(lnum);
5544     else
5545 	retvar->var_val.var_number = -1;
5546 }
5547 
5548 static int inputsecret_flag = 0;
5549 
5550 /*
5551  * "input()" function
5552  *     Also handles inputsecret() when inputsecret is set.
5553  */
5554     static void
5555 f_input(argvars, retvar)
5556     VAR		argvars;
5557     VAR		retvar;
5558 {
5559     char_u	*prompt = get_var_string(&argvars[0]);
5560     char_u	*p = NULL;
5561     int		c;
5562     char_u	buf[NUMBUFLEN];
5563     int		cmd_silent_save = cmd_silent;
5564 
5565     retvar->var_type = VAR_STRING;
5566 
5567 #ifdef NO_CONSOLE_INPUT
5568     /* While starting up, there is no place to enter text. */
5569     if (no_console_input())
5570     {
5571 	retvar->var_val.var_string = NULL;
5572 	return;
5573     }
5574 #endif
5575 
5576     cmd_silent = FALSE;		/* Want to see the prompt. */
5577     if (prompt != NULL)
5578     {
5579 	/* Only the part of the message after the last NL is considered as
5580 	 * prompt for the command line */
5581 	p = vim_strrchr(prompt, '\n');
5582 	if (p == NULL)
5583 	    p = prompt;
5584 	else
5585 	{
5586 	    ++p;
5587 	    c = *p;
5588 	    *p = NUL;
5589 	    msg_start();
5590 	    msg_clr_eos();
5591 	    msg_puts_attr(prompt, echo_attr);
5592 	    msg_didout = FALSE;
5593 	    msg_starthere();
5594 	    *p = c;
5595 	}
5596 	cmdline_row = msg_row;
5597     }
5598 
5599     if (argvars[1].var_type != VAR_UNKNOWN)
5600 	stuffReadbuffSpec(get_var_string_buf(&argvars[1], buf));
5601 
5602     retvar->var_val.var_string =
5603 		getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr);
5604 
5605     /* since the user typed this, no need to wait for return */
5606     need_wait_return = FALSE;
5607     msg_didout = FALSE;
5608     cmd_silent = cmd_silent_save;
5609 }
5610 
5611 /*
5612  * "inputdialog()" function
5613  */
5614     static void
5615 f_inputdialog(argvars, retvar)
5616     VAR		argvars;
5617     VAR		retvar;
5618 {
5619 #if defined(FEAT_GUI_TEXTDIALOG)
5620     /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */
5621     if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL)
5622     {
5623 	char_u	*message;
5624 	char_u	buf[NUMBUFLEN];
5625 
5626 	message = get_var_string(&argvars[0]);
5627 	if (argvars[1].var_type != VAR_UNKNOWN)
5628 	{
5629 	    STRNCPY(IObuff, get_var_string_buf(&argvars[1], buf), IOSIZE);
5630 	    IObuff[IOSIZE - 1] = NUL;
5631 	}
5632 	else
5633 	    IObuff[0] = NUL;
5634 	if (do_dialog(VIM_QUESTION, NULL, message, (char_u *)_("&OK\n&Cancel"),
5635 							      1, IObuff) == 1)
5636 	    retvar->var_val.var_string = vim_strsave(IObuff);
5637 	else
5638 	{
5639 	    if (argvars[1].var_type != VAR_UNKNOWN
5640 					&& argvars[2].var_type != VAR_UNKNOWN)
5641 		retvar->var_val.var_string = vim_strsave(
5642 					get_var_string_buf(&argvars[2], buf));
5643 	    else
5644 		retvar->var_val.var_string = NULL;
5645 	}
5646 	retvar->var_type = VAR_STRING;
5647     }
5648     else
5649 #endif
5650 	f_input(argvars, retvar);
5651 }
5652 
5653 static garray_T	    ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL};
5654 
5655 /*
5656  * "inputrestore()" function
5657  */
5658 /*ARGSUSED*/
5659     static void
5660 f_inputrestore(argvars, retvar)
5661     VAR		argvars;
5662     VAR		retvar;
5663 {
5664     if (ga_userinput.ga_len > 0)
5665     {
5666 	--ga_userinput.ga_len;
5667 	++ga_userinput.ga_room;
5668 	restore_typeahead((tasave_T *)(ga_userinput.ga_data)
5669 						       + ga_userinput.ga_len);
5670 	retvar->var_val.var_number = 0; /* OK */
5671     }
5672     else if (p_verbose > 1)
5673     {
5674 	msg((char_u *)_("called inputrestore() more often than inputsave()"));
5675 	retvar->var_val.var_number = 1; /* Failed */
5676     }
5677 }
5678 
5679 /*
5680  * "inputsave()" function
5681  */
5682 /*ARGSUSED*/
5683     static void
5684 f_inputsave(argvars, retvar)
5685     VAR		argvars;
5686     VAR		retvar;
5687 {
5688     /* Add an entry to the stack of typehead storage. */
5689     if (ga_grow(&ga_userinput, 1) == OK)
5690     {
5691 	save_typeahead((tasave_T *)(ga_userinput.ga_data)
5692 						       + ga_userinput.ga_len);
5693 	++ga_userinput.ga_len;
5694 	--ga_userinput.ga_room;
5695 	retvar->var_val.var_number = 0; /* OK */
5696     }
5697     else
5698 	retvar->var_val.var_number = 1; /* Failed */
5699 }
5700 
5701 /*
5702  * "inputsecret()" function
5703  */
5704     static void
5705 f_inputsecret(argvars, retvar)
5706     VAR		argvars;
5707     VAR		retvar;
5708 {
5709     ++cmdline_star;
5710     ++inputsecret_flag;
5711     f_input(argvars, retvar);
5712     --cmdline_star;
5713     --inputsecret_flag;
5714 }
5715 
5716 /*
5717  * "isdirectory()" function
5718  */
5719     static void
5720 f_isdirectory(argvars, retvar)
5721     VAR		argvars;
5722     VAR		retvar;
5723 {
5724     retvar->var_val.var_number = mch_isdir(get_var_string(&argvars[0]));
5725 }
5726 
5727 /*
5728  * "last_buffer_nr()" function.
5729  */
5730 /*ARGSUSED*/
5731     static void
5732 f_last_buffer_nr(argvars, retvar)
5733     VAR		argvars;
5734     VAR		retvar;
5735 {
5736     int		n = 0;
5737     buf_T	*buf;
5738 
5739     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
5740 	if (n < buf->b_fnum)
5741 	    n = buf->b_fnum;
5742 
5743     retvar->var_val.var_number = n;
5744 }
5745 
5746 /*
5747  * "line(string)" function
5748  */
5749     static void
5750 f_line(argvars, retvar)
5751     VAR		argvars;
5752     VAR		retvar;
5753 {
5754     linenr_T	lnum = 0;
5755     pos_T	*fp;
5756 
5757     fp = var2fpos(&argvars[0], TRUE);
5758     if (fp != NULL)
5759 	lnum = fp->lnum;
5760     retvar->var_val.var_number = lnum;
5761 }
5762 
5763 /*
5764  * "line2byte(lnum)" function
5765  */
5766 /*ARGSUSED*/
5767     static void
5768 f_line2byte(argvars, retvar)
5769     VAR		argvars;
5770     VAR		retvar;
5771 {
5772 #ifndef FEAT_BYTEOFF
5773     retvar->var_val.var_number = -1;
5774 #else
5775     linenr_T	lnum;
5776 
5777     lnum = get_var_lnum(argvars);
5778     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
5779 	retvar->var_val.var_number = -1;
5780     else
5781 	retvar->var_val.var_number = ml_find_line_or_offset(curbuf, lnum, NULL);
5782     if (retvar->var_val.var_number >= 0)
5783 	++retvar->var_val.var_number;
5784 #endif
5785 }
5786 
5787 /*
5788  * "lispindent(lnum)" function
5789  */
5790     static void
5791 f_lispindent(argvars, retvar)
5792     VAR		argvars;
5793     VAR		retvar;
5794 {
5795 #ifdef FEAT_LISP
5796     pos_T	pos;
5797     linenr_T	lnum;
5798 
5799     pos = curwin->w_cursor;
5800     lnum = get_var_lnum(argvars);
5801     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
5802     {
5803 	curwin->w_cursor.lnum = lnum;
5804 	retvar->var_val.var_number = get_lisp_indent();
5805 	curwin->w_cursor = pos;
5806     }
5807     else
5808 #endif
5809 	retvar->var_val.var_number = -1;
5810 }
5811 
5812 /*
5813  * "localtime()" function
5814  */
5815 /*ARGSUSED*/
5816     static void
5817 f_localtime(argvars, retvar)
5818     VAR		argvars;
5819     VAR		retvar;
5820 {
5821     retvar->var_val.var_number = (varnumber_T)time(NULL);
5822 }
5823 
5824 /*
5825  * "maparg()" function
5826  */
5827     static void
5828 f_maparg(argvars, retvar)
5829     VAR		argvars;
5830     VAR		retvar;
5831 {
5832     get_maparg(argvars, retvar, TRUE);
5833 }
5834 
5835 /*
5836  * "mapcheck()" function
5837  */
5838     static void
5839 f_mapcheck(argvars, retvar)
5840     VAR		argvars;
5841     VAR		retvar;
5842 {
5843     get_maparg(argvars, retvar, FALSE);
5844 }
5845 
5846     static void
5847 get_maparg(argvars, retvar, exact)
5848     VAR		argvars;
5849     VAR		retvar;
5850     int		exact;
5851 {
5852     char_u	*keys;
5853     char_u	*which;
5854     char_u	buf[NUMBUFLEN];
5855     char_u	*keys_buf = NULL;
5856     char_u	*rhs;
5857     int		mode;
5858     garray_T	ga;
5859 
5860     /* return empty string for failure */
5861     retvar->var_type = VAR_STRING;
5862     retvar->var_val.var_string = NULL;
5863 
5864     keys = get_var_string(&argvars[0]);
5865     if (*keys == NUL)
5866 	return;
5867 
5868     if (argvars[1].var_type != VAR_UNKNOWN)
5869 	which = get_var_string_buf(&argvars[1], buf);
5870     else
5871 	which = (char_u *)"";
5872     mode = get_map_mode(&which, 0);
5873 
5874     keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE);
5875     rhs = check_map(keys, mode, exact);
5876     vim_free(keys_buf);
5877     if (rhs != NULL)
5878     {
5879 	ga_init(&ga);
5880 	ga.ga_itemsize = 1;
5881 	ga.ga_growsize = 40;
5882 
5883 	while (*rhs != NUL)
5884 	    ga_concat(&ga, str2special(&rhs, FALSE));
5885 
5886 	ga_append(&ga, NUL);
5887 	retvar->var_val.var_string = (char_u *)ga.ga_data;
5888     }
5889 }
5890 
5891 /*
5892  * "match()" function
5893  */
5894     static void
5895 f_match(argvars, retvar)
5896     VAR		argvars;
5897     VAR		retvar;
5898 {
5899     find_some_match(argvars, retvar, 1);
5900 }
5901 
5902 /*
5903  * "matchend()" function
5904  */
5905     static void
5906 f_matchend(argvars, retvar)
5907     VAR		argvars;
5908     VAR		retvar;
5909 {
5910     find_some_match(argvars, retvar, 0);
5911 }
5912 
5913 /*
5914  * "matchstr()" function
5915  */
5916     static void
5917 f_matchstr(argvars, retvar)
5918     VAR		argvars;
5919     VAR		retvar;
5920 {
5921     find_some_match(argvars, retvar, 2);
5922 }
5923 
5924     static void
5925 find_some_match(argvars, retvar, type)
5926     VAR		argvars;
5927     VAR		retvar;
5928     int		type;
5929 {
5930     char_u	*str;
5931     char_u	*expr;
5932     char_u	*pat;
5933     regmatch_T	regmatch;
5934     char_u	patbuf[NUMBUFLEN];
5935     char_u	*save_cpo;
5936     long	start = 0;
5937     long	nth = 1;
5938     int		match;
5939 
5940     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
5941     save_cpo = p_cpo;
5942     p_cpo = (char_u *)"";
5943 
5944     expr = str = get_var_string(&argvars[0]);
5945     pat = get_var_string_buf(&argvars[1], patbuf);
5946 
5947     if (type == 2)
5948     {
5949 	retvar->var_type = VAR_STRING;
5950 	retvar->var_val.var_string = NULL;
5951     }
5952     else
5953 	retvar->var_val.var_number = -1;
5954 
5955     if (argvars[2].var_type != VAR_UNKNOWN)
5956     {
5957 	start = get_var_number(&argvars[2]);
5958 	if (start < 0)
5959 	    start = 0;
5960 	if (start > (long)STRLEN(str))
5961 	    goto theend;
5962 	str += start;
5963 
5964 	if (argvars[3].var_type != VAR_UNKNOWN)
5965 	    nth = get_var_number(&argvars[3]);
5966     }
5967 
5968     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
5969     if (regmatch.regprog != NULL)
5970     {
5971 	regmatch.rm_ic = p_ic;
5972 
5973 	while (1)
5974 	{
5975 	    match = vim_regexec_nl(&regmatch, str, (colnr_T)0);
5976 	    if (!match || --nth <= 0)
5977 		break;
5978 	    /* Advance to just after the match. */
5979 #ifdef FEAT_MBYTE
5980 	    str = regmatch.startp[0] + mb_ptr2len_check(regmatch.startp[0]);
5981 #else
5982 	    str = regmatch.startp[0] + 1;
5983 #endif
5984 	}
5985 
5986 	if (match)
5987 	{
5988 	    if (type == 2)
5989 		retvar->var_val.var_string = vim_strnsave(regmatch.startp[0],
5990 				(int)(regmatch.endp[0] - regmatch.startp[0]));
5991 	    else
5992 	    {
5993 		if (type != 0)
5994 		    retvar->var_val.var_number =
5995 				      (varnumber_T)(regmatch.startp[0] - str);
5996 		else
5997 		    retvar->var_val.var_number =
5998 					(varnumber_T)(regmatch.endp[0] - str);
5999 		retvar->var_val.var_number += str - expr;
6000 	    }
6001 	}
6002 	vim_free(regmatch.regprog);
6003     }
6004 
6005 theend:
6006     p_cpo = save_cpo;
6007 }
6008 
6009 /*
6010  * "mode()" function
6011  */
6012 /*ARGSUSED*/
6013     static void
6014 f_mode(argvars, retvar)
6015     VAR		argvars;
6016     VAR		retvar;
6017 {
6018     char_u	buf[2];
6019 
6020 #ifdef FEAT_VISUAL
6021     if (VIsual_active)
6022     {
6023 	if (VIsual_select)
6024 	    buf[0] = VIsual_mode + 's' - 'v';
6025 	else
6026 	    buf[0] = VIsual_mode;
6027     }
6028     else
6029 #endif
6030 	if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
6031 	buf[0] = 'r';
6032     else if (State & INSERT)
6033     {
6034 	if (State & REPLACE_FLAG)
6035 	    buf[0] = 'R';
6036 	else
6037 	    buf[0] = 'i';
6038     }
6039     else if (State & CMDLINE)
6040 	buf[0] = 'c';
6041     else
6042 	buf[0] = 'n';
6043 
6044     buf[1] = NUL;
6045     retvar->var_val.var_string = vim_strsave(buf);
6046     retvar->var_type = VAR_STRING;
6047 }
6048 
6049 /*
6050  * "nr2char()" function
6051  */
6052     static void
6053 f_nr2char(argvars, retvar)
6054     VAR		argvars;
6055     VAR		retvar;
6056 {
6057     char_u	buf[NUMBUFLEN];
6058 
6059 #ifdef FEAT_MBYTE
6060     if (has_mbyte)
6061 	buf[(*mb_char2bytes)((int)get_var_number(&argvars[0]), buf)] = NUL;
6062     else
6063 #endif
6064     {
6065 	buf[0] = (char_u)get_var_number(&argvars[0]);
6066 	buf[1] = NUL;
6067     }
6068     retvar->var_type = VAR_STRING;
6069     retvar->var_val.var_string = vim_strsave(buf);
6070 }
6071 
6072 /*
6073  * "rename({from}, {to})" function
6074  */
6075     static void
6076 f_rename(argvars, retvar)
6077     VAR		argvars;
6078     VAR		retvar;
6079 {
6080     char_u	buf[NUMBUFLEN];
6081 
6082     if (check_restricted() || check_secure())
6083 	retvar->var_val.var_number = -1;
6084     else
6085 	retvar->var_val.var_number = vim_rename(get_var_string(&argvars[0]),
6086 					get_var_string_buf(&argvars[1], buf));
6087 }
6088 
6089 /*
6090  * "resolve()" function
6091  */
6092     static void
6093 f_resolve(argvars, retvar)
6094     VAR		argvars;
6095     VAR		retvar;
6096 {
6097     char_u	*p;
6098 
6099     p = get_var_string(&argvars[0]);
6100 #ifdef FEAT_SHORTCUT
6101     {
6102 	char_u	*v = NULL;
6103 
6104 	v = mch_resolve_shortcut(p);
6105 	if (v != NULL)
6106 	    retvar->var_val.var_string = v;
6107 	else
6108 	    retvar->var_val.var_string = vim_strsave(p);
6109     }
6110 #else
6111 # ifdef HAVE_READLINK
6112     {
6113 	char_u	buf[MAXPATHL + 1];
6114 	char_u	*cpy;
6115 	int	len;
6116 	char_u	*remain = NULL;
6117 	char_u	*q;
6118 	int	is_relative_to_current = FALSE;
6119 	int	has_trailing_pathsep = FALSE;
6120 	int	limit = 100;
6121 
6122 	p = vim_strsave(p);
6123 
6124 	if (p[0] == '.' && (vim_ispathsep(p[1])
6125 				   || (p[1] == '.' && (vim_ispathsep(p[2])))))
6126 	    is_relative_to_current = TRUE;
6127 
6128 	len = STRLEN(p);
6129 	if (len > 0 && vim_ispathsep(p[len-1]))
6130 	    has_trailing_pathsep = TRUE;
6131 
6132 	q = getnextcomp(p);
6133 	if (*q != NUL)
6134 	{
6135 	    /* Separate the first path component in "p", and keep the
6136 	     * remainder (beginning with the path separator). */
6137 	    remain = vim_strsave(q - 1);
6138 	    q[-1] = NUL;
6139 	}
6140 
6141 	for (;;)
6142 	{
6143 	    for (;;)
6144 	    {
6145 		len = readlink((char *)p, (char *)buf, MAXPATHL);
6146 		if (len <= 0)
6147 		    break;
6148 		buf[len] = NUL;
6149 
6150 		if (limit-- == 0)
6151 		{
6152 		    vim_free(p);
6153 		    vim_free(remain);
6154 		    EMSG(_("E655: Too many symbolic links (cycle?)"));
6155 		    retvar->var_val.var_string = NULL;
6156 		    goto fail;
6157 		}
6158 
6159 		/* Ensure that the result will have a trailing path separator
6160 		 * if the argument has one. */
6161 		if (remain == NULL && has_trailing_pathsep)
6162 		    add_pathsep(buf);
6163 
6164 		/* Separate the first path component in the link value and
6165 		 * concatenate the remainders. */
6166 		q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf);
6167 		if (*q != NUL)
6168 		{
6169 		    if (remain == NULL)
6170 			remain = vim_strsave(q - 1);
6171 		    else
6172 		    {
6173 			cpy = vim_strnsave(q-1, STRLEN(q-1)+STRLEN(remain));
6174 			if (cpy != NULL)
6175 			{
6176 			    STRCAT(cpy, remain);
6177 			    vim_free(remain);
6178 			    remain = cpy;
6179 			}
6180 		    }
6181 		    q[-1] = NUL;
6182 		}
6183 
6184 		q = gettail(p);
6185 		if (q > p && *q == NUL)
6186 		{
6187 		    /* Ignore trailing path separator. */
6188 		    q[-1] = NUL;
6189 		    q = gettail(p);
6190 		}
6191 		if (q > p && !mch_isFullName(buf))
6192 		{
6193 		    /* symlink is relative to directory of argument */
6194 		    cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
6195 		    if (cpy != NULL)
6196 		    {
6197 			STRCPY(cpy, p);
6198 			STRCPY(gettail(cpy), buf);
6199 			vim_free(p);
6200 			p = cpy;
6201 		    }
6202 		}
6203 		else
6204 		{
6205 		    vim_free(p);
6206 		    p = vim_strsave(buf);
6207 		}
6208 	    }
6209 
6210 	    if (remain == NULL)
6211 		break;
6212 
6213 	    /* Append the first path component of "remain" to "p". */
6214 	    q = getnextcomp(remain + 1);
6215 	    len = q - remain - (*q != NUL);
6216 	    cpy = vim_strnsave(p, STRLEN(p) + len);
6217 	    if (cpy != NULL)
6218 	    {
6219 		STRNCAT(cpy, remain, len);
6220 		vim_free(p);
6221 		p = cpy;
6222 	    }
6223 	    /* Shorten "remain". */
6224 	    if (*q != NUL)
6225 		STRCPY(remain, q - 1);
6226 	    else
6227 	    {
6228 		vim_free(remain);
6229 		remain = NULL;
6230 	    }
6231 	}
6232 
6233 	/* If the result is a relative path name, make it explicitly relative to
6234 	 * the current directory if and only if the argument had this form. */
6235 	if (!vim_ispathsep(*p))
6236 	{
6237 	    if (is_relative_to_current
6238 		    && *p != NUL
6239 		    && !(p[0] == '.'
6240 			&& (p[1] == NUL
6241 			    || vim_ispathsep(p[1])
6242 			    || (p[1] == '.'
6243 				&& (p[2] == NUL
6244 				    || vim_ispathsep(p[2]))))))
6245 	    {
6246 		/* Prepend "./". */
6247 		cpy = vim_strnsave((char_u *)"./", 2 + STRLEN(p));
6248 		if (cpy != NULL)
6249 		{
6250 		    STRCAT(cpy, p);
6251 		    vim_free(p);
6252 		    p = cpy;
6253 		}
6254 	    }
6255 	    else if (!is_relative_to_current)
6256 	    {
6257 		/* Strip leading "./". */
6258 		q = p;
6259 		while (q[0] == '.' && vim_ispathsep(q[1]))
6260 		    q += 2;
6261 		if (q > p)
6262 		    mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1);
6263 	    }
6264 	}
6265 
6266 	/* Ensure that the result will have no trailing path separator
6267 	 * if the argument had none.  But keep "/" or "//". */
6268 	if (!has_trailing_pathsep)
6269 	{
6270 	    q = p + STRLEN(p);
6271 	    while ((q > p + 2 || (q == p + 2 && !vim_ispathsep(*p)))
6272 		   && vim_ispathsep(q[-1]))
6273 		--q;
6274 	    *q = NUL;
6275 	}
6276 
6277 	retvar->var_val.var_string = p;
6278     }
6279 # else
6280     retvar->var_val.var_string = vim_strsave(p);
6281 # endif
6282 #endif
6283 
6284     simplify_filename(retvar->var_val.var_string);
6285 
6286 #ifdef HAVE_READLINK
6287 fail:
6288 #endif
6289     retvar->var_type = VAR_STRING;
6290 }
6291 
6292 /*
6293  * "simplify()" function
6294  */
6295     static void
6296 f_simplify(argvars, retvar)
6297     VAR		argvars;
6298     VAR		retvar;
6299 {
6300     char_u	*p;
6301 
6302     p = get_var_string(&argvars[0]);
6303     retvar->var_val.var_string = vim_strsave(p);
6304     simplify_filename(retvar->var_val.var_string);	/* simplify in place */
6305     retvar->var_type = VAR_STRING;
6306 }
6307 
6308 /*
6309  * "search()" function
6310  */
6311     static void
6312 f_search(argvars, retvar)
6313     VAR		argvars;
6314     VAR		retvar;
6315 {
6316     char_u	*pat;
6317     pos_T	pos;
6318     int		save_p_ws = p_ws;
6319     int		dir;
6320 
6321     pat = get_var_string(&argvars[0]);
6322     dir = get_search_arg(&argvars[1], NULL);	/* may set p_ws */
6323 
6324     pos = curwin->w_cursor;
6325     if (searchit(curwin, curbuf, &pos, dir, pat, 1L,
6326 					      SEARCH_KEEP, RE_SEARCH) != FAIL)
6327     {
6328 	retvar->var_val.var_number = pos.lnum;
6329 	curwin->w_cursor = pos;
6330 	/* "/$" will put the cursor after the end of the line, may need to
6331 	 * correct that here */
6332 	check_cursor();
6333     }
6334     else
6335 	retvar->var_val.var_number = 0;
6336     p_ws = save_p_ws;
6337 }
6338 
6339 #define SP_NOMOVE	1	/* don't move cursor */
6340 #define SP_REPEAT	2	/* repeat to find outer pair */
6341 #define SP_RETCOUNT	4	/* return matchcount */
6342 
6343 /*
6344  * "searchpair()" function
6345  */
6346     static void
6347 f_searchpair(argvars, retvar)
6348     VAR		argvars;
6349     VAR		retvar;
6350 {
6351     char_u	*spat, *mpat, *epat;
6352     char_u	*skip;
6353     char_u	*pat, *pat2, *pat3;
6354     pos_T	pos;
6355     pos_T	firstpos;
6356     pos_T	save_cursor;
6357     pos_T	save_pos;
6358     int		save_p_ws = p_ws;
6359     char_u	*save_cpo;
6360     int		dir;
6361     int		flags = 0;
6362     char_u	nbuf1[NUMBUFLEN];
6363     char_u	nbuf2[NUMBUFLEN];
6364     char_u	nbuf3[NUMBUFLEN];
6365     int		n;
6366     int		r;
6367     int		nest = 1;
6368     int		err;
6369 
6370     retvar->var_val.var_number = 0;	/* default: FAIL */
6371 
6372     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
6373     save_cpo = p_cpo;
6374     p_cpo = (char_u *)"";
6375 
6376     /* Get the three pattern arguments: start, middle, end. */
6377     spat = get_var_string(&argvars[0]);
6378     mpat = get_var_string_buf(&argvars[1], nbuf1);
6379     epat = get_var_string_buf(&argvars[2], nbuf2);
6380 
6381     /* Make two search patterns: start/end (pat2, for in nested pairs) and
6382      * start/middle/end (pat3, for the top pair). */
6383     pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
6384     pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
6385     if (pat2 == NULL || pat3 == NULL)
6386 	goto theend;
6387     sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
6388     if (*mpat == NUL)
6389 	STRCPY(pat3, pat2);
6390     else
6391 	sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
6392 							    spat, epat, mpat);
6393 
6394     /* Handle the optional fourth argument: flags */
6395     dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
6396 
6397     /* Optional fifth argument: skip expresion */
6398     if (argvars[3].var_type == VAR_UNKNOWN
6399 	    || argvars[4].var_type == VAR_UNKNOWN)
6400 	skip = (char_u *)"";
6401     else
6402 	skip = get_var_string_buf(&argvars[4], nbuf3);
6403 
6404     save_cursor = curwin->w_cursor;
6405     pos = curwin->w_cursor;
6406     firstpos.lnum = 0;
6407     pat = pat3;
6408     for (;;)
6409     {
6410 	n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
6411 						      SEARCH_KEEP, RE_SEARCH);
6412 	if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
6413 	    /* didn't find it or found the first match again: FAIL */
6414 	    break;
6415 
6416 	if (firstpos.lnum == 0)
6417 	    firstpos = pos;
6418 
6419 	/* If the skip pattern matches, ignore this match. */
6420 	if (*skip != NUL)
6421 	{
6422 	    save_pos = curwin->w_cursor;
6423 	    curwin->w_cursor = pos;
6424 	    r = eval_to_bool(skip, &err, NULL, FALSE);
6425 	    curwin->w_cursor = save_pos;
6426 	    if (err)
6427 	    {
6428 		/* Evaluating {skip} caused an error, break here. */
6429 		curwin->w_cursor = save_cursor;
6430 		retvar->var_val.var_number = -1;
6431 		break;
6432 	    }
6433 	    if (r)
6434 		continue;
6435 	}
6436 
6437 	if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2))
6438 	{
6439 	    /* Found end when searching backwards or start when searching
6440 	     * forward: nested pair. */
6441 	    ++nest;
6442 	    pat = pat2;		/* nested, don't search for middle */
6443 	}
6444 	else
6445 	{
6446 	    /* Found end when searching forward or start when searching
6447 	     * backward: end of (nested) pair; or found middle in outer pair. */
6448 	    if (--nest == 1)
6449 		pat = pat3;	/* outer level, search for middle */
6450 	}
6451 
6452 	if (nest == 0)
6453 	{
6454 	    /* Found the match: return matchcount or line number. */
6455 	    if (flags & SP_RETCOUNT)
6456 		++retvar->var_val.var_number;
6457 	    else
6458 		retvar->var_val.var_number = pos.lnum;
6459 	    curwin->w_cursor = pos;
6460 	    if (!(flags & SP_REPEAT))
6461 		break;
6462 	    nest = 1;	    /* search for next unmatched */
6463 	}
6464     }
6465 
6466     /* If 'n' flag is used or search failed: restore cursor position. */
6467     if ((flags & SP_NOMOVE) || retvar->var_val.var_number == 0)
6468 	curwin->w_cursor = save_cursor;
6469 
6470 theend:
6471     vim_free(pat2);
6472     vim_free(pat3);
6473     p_ws = save_p_ws;
6474     p_cpo = save_cpo;
6475 }
6476 
6477     static int
6478 get_search_arg(varp, flagsp)
6479     VAR		varp;
6480     int		*flagsp;
6481 {
6482     int		dir = FORWARD;
6483     char_u	*flags;
6484     char_u	nbuf[NUMBUFLEN];
6485 
6486     if (varp->var_type != VAR_UNKNOWN)
6487     {
6488 	flags = get_var_string_buf(varp, nbuf);
6489 	if (vim_strchr(flags, 'b') != NULL)
6490 	    dir = BACKWARD;
6491 	if (vim_strchr(flags, 'w') != NULL)
6492 	    p_ws = TRUE;
6493 	if (vim_strchr(flags, 'W') != NULL)
6494 	    p_ws = FALSE;
6495 	if (flagsp != NULL)
6496 	{
6497 	    if (vim_strchr(flags, 'n') != NULL)
6498 		*flagsp |= SP_NOMOVE;
6499 	    if (vim_strchr(flags, 'r') != NULL)
6500 		*flagsp |= SP_REPEAT;
6501 	    if (vim_strchr(flags, 'm') != NULL)
6502 		*flagsp |= SP_RETCOUNT;
6503 	}
6504     }
6505     return dir;
6506 }
6507 
6508 /*
6509  * "setbufvar()" function
6510  */
6511 /*ARGSUSED*/
6512     static void
6513 f_setbufvar(argvars, retvar)
6514     VAR		argvars;
6515     VAR		retvar;
6516 {
6517     buf_T	*buf;
6518 #ifdef FEAT_AUTOCMD
6519     aco_save_T	aco;
6520 #else
6521     buf_T	*save_curbuf;
6522 #endif
6523     char_u	*varname, *bufvarname;
6524     VAR		varp;
6525     char_u	nbuf[NUMBUFLEN];
6526 
6527     if (check_restricted() || check_secure())
6528 	return;
6529     ++emsg_off;
6530     buf = get_buf_var(&argvars[0]);
6531     varname = get_var_string(&argvars[1]);
6532     varp = &argvars[2];
6533 
6534     if (buf != NULL && varname != NULL && varp != NULL)
6535     {
6536 	/* set curbuf to be our buf, temporarily */
6537 #ifdef FEAT_AUTOCMD
6538 	aucmd_prepbuf(&aco, buf);
6539 #else
6540 	save_curbuf = curbuf;
6541 	curbuf = buf;
6542 #endif
6543 
6544 	if (*varname == '&')
6545 	{
6546 	    ++varname;
6547 	    set_option_value(varname, get_var_number(varp),
6548 				   get_var_string_buf(varp, nbuf), OPT_LOCAL);
6549 	}
6550 	else
6551 	{
6552 	    bufvarname = alloc((unsigned)STRLEN(varname) + 3);
6553 	    if (bufvarname != NULL)
6554 	    {
6555 		STRCPY(bufvarname, "b:");
6556 		STRCPY(bufvarname + 2, varname);
6557 		set_var(bufvarname, varp);
6558 		vim_free(bufvarname);
6559 	    }
6560 	}
6561 
6562 	/* reset notion of buffer */
6563 #ifdef FEAT_AUTOCMD
6564 	aucmd_restbuf(&aco);
6565 #else
6566 	curbuf = save_curbuf;
6567 #endif
6568     }
6569     --emsg_off;
6570 }
6571 
6572 /*
6573  * "setcmdpos()" function
6574  */
6575     static void
6576 f_setcmdpos(argvars, retvar)
6577     VAR		argvars;
6578     VAR		retvar;
6579 {
6580     retvar->var_val.var_number = set_cmdline_pos(
6581 					(int)get_var_number(&argvars[0]) - 1);
6582 }
6583 
6584 /*
6585  * "setline()" function
6586  */
6587     static void
6588 f_setline(argvars, retvar)
6589     VAR		argvars;
6590     VAR		retvar;
6591 {
6592     linenr_T	lnum;
6593     char_u	*line;
6594 
6595     lnum = get_var_lnum(argvars);
6596     line = get_var_string(&argvars[1]);
6597     retvar->var_val.var_number = 1;		/* FAIL is default */
6598 
6599     if (lnum >= 1
6600 	    && lnum <= curbuf->b_ml.ml_line_count
6601 	    && u_savesub(lnum) == OK
6602 	    && ml_replace(lnum, line, TRUE) == OK)
6603     {
6604 	changed_bytes(lnum, 0);
6605 	check_cursor_col();
6606 	retvar->var_val.var_number = 0;
6607     }
6608 }
6609 
6610 /*
6611  * "setreg()" function
6612  */
6613     static void
6614 f_setreg(argvars, retvar)
6615     VAR		argvars;
6616     VAR		retvar;
6617 {
6618     int		regname;
6619     char_u	*strregname;
6620     char_u	*stropt;
6621     int		append;
6622     char_u	yank_type;
6623     long	block_len;
6624 
6625     block_len = -1;
6626     yank_type = MAUTO;
6627     append = FALSE;
6628 
6629     strregname = get_var_string(argvars);
6630     retvar->var_val.var_number = 1;		/* FAIL is default */
6631 
6632     regname = (strregname == NULL ? '"' : *strregname);
6633     if (regname == 0 || regname == '@')
6634 	regname = '"';
6635     else if (regname == '=')
6636 	return;
6637 
6638     if (argvars[2].var_type != VAR_UNKNOWN)
6639     {
6640 	for (stropt = get_var_string(&argvars[2]); *stropt != NUL; ++stropt)
6641 	    switch (*stropt)
6642 	    {
6643 		case 'a': case 'A':	/* append */
6644 		    append = TRUE;
6645 		    break;
6646 		case 'v': case 'c':	/* character-wise selection */
6647 		    yank_type = MCHAR;
6648 		    break;
6649 		case 'V': case 'l':	/* line-wise selection */
6650 		    yank_type = MLINE;
6651 		    break;
6652 #ifdef FEAT_VISUAL
6653 		case 'b': case Ctrl_V:	/* block-wise selection */
6654 		    yank_type = MBLOCK;
6655 		    if (VIM_ISDIGIT(stropt[1]))
6656 		    {
6657 			++stropt;
6658 			block_len = getdigits(&stropt) - 1;
6659 			--stropt;
6660 		    }
6661 		    break;
6662 #endif
6663 	    }
6664     }
6665 
6666     write_reg_contents_ex(regname, get_var_string(&argvars[1]), -1,
6667 						append, yank_type, block_len);
6668     retvar->var_val.var_number = 0;
6669 }
6670 
6671 
6672 /*
6673  * "setwinvar(expr)" function
6674  */
6675 /*ARGSUSED*/
6676     static void
6677 f_setwinvar(argvars, retvar)
6678     VAR		argvars;
6679     VAR		retvar;
6680 {
6681     win_T	*win;
6682 #ifdef FEAT_WINDOWS
6683     win_T	*save_curwin;
6684 #endif
6685     char_u	*varname, *winvarname;
6686     VAR		varp;
6687     char_u	nbuf[NUMBUFLEN];
6688 
6689     if (check_restricted() || check_secure())
6690 	return;
6691     ++emsg_off;
6692     win = find_win_by_nr(&argvars[0]);
6693     varname = get_var_string(&argvars[1]);
6694     varp = &argvars[2];
6695 
6696     if (win != NULL && varname != NULL && varp != NULL)
6697     {
6698 #ifdef FEAT_WINDOWS
6699 	/* set curwin to be our win, temporarily */
6700 	save_curwin = curwin;
6701 	curwin = win;
6702 	curbuf = curwin->w_buffer;
6703 #endif
6704 
6705 	if (*varname == '&')
6706 	{
6707 	    ++varname;
6708 	    set_option_value(varname, get_var_number(varp),
6709 				   get_var_string_buf(varp, nbuf), OPT_LOCAL);
6710 	}
6711 	else
6712 	{
6713 	    winvarname = alloc((unsigned)STRLEN(varname) + 3);
6714 	    if (winvarname != NULL)
6715 	    {
6716 		STRCPY(winvarname, "w:");
6717 		STRCPY(winvarname + 2, varname);
6718 		set_var(winvarname, varp);
6719 		vim_free(winvarname);
6720 	    }
6721 	}
6722 
6723 #ifdef FEAT_WINDOWS
6724 	/* Restore current window, if it's still valid (autocomands can make
6725 	 * it invalid). */
6726 	if (win_valid(save_curwin))
6727 	{
6728 	    curwin = save_curwin;
6729 	    curbuf = curwin->w_buffer;
6730 	}
6731 #endif
6732     }
6733     --emsg_off;
6734 }
6735 
6736 /*
6737  * "nextnonblank()" function
6738  */
6739     static void
6740 f_nextnonblank(argvars, retvar)
6741     VAR		argvars;
6742     VAR		retvar;
6743 {
6744     linenr_T	lnum;
6745 
6746     for (lnum = get_var_lnum(argvars); ; ++lnum)
6747     {
6748 	if (lnum > curbuf->b_ml.ml_line_count)
6749 	{
6750 	    lnum = 0;
6751 	    break;
6752 	}
6753 	if (*skipwhite(ml_get(lnum)) != NUL)
6754 	    break;
6755     }
6756     retvar->var_val.var_number = lnum;
6757 }
6758 
6759 /*
6760  * "prevnonblank()" function
6761  */
6762     static void
6763 f_prevnonblank(argvars, retvar)
6764     VAR		argvars;
6765     VAR		retvar;
6766 {
6767     linenr_T	lnum;
6768 
6769     lnum = get_var_lnum(argvars);
6770     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
6771 	lnum = 0;
6772     else
6773 	while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
6774 	    --lnum;
6775     retvar->var_val.var_number = lnum;
6776 }
6777 
6778 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
6779 static void make_connection __ARGS((void));
6780 static int check_connection __ARGS((void));
6781 
6782     static void
6783 make_connection()
6784 {
6785     if (X_DISPLAY == NULL
6786 # ifdef FEAT_GUI
6787 	    && !gui.in_use
6788 # endif
6789 	    )
6790     {
6791 	x_force_connect = TRUE;
6792 	setup_term_clip();
6793 	x_force_connect = FALSE;
6794     }
6795 }
6796 
6797     static int
6798 check_connection()
6799 {
6800     make_connection();
6801     if (X_DISPLAY == NULL)
6802     {
6803 	EMSG(_("E240: No connection to Vim server"));
6804 	return FAIL;
6805     }
6806     return OK;
6807 }
6808 #endif
6809 
6810 /*ARGSUSED*/
6811     static void
6812 f_serverlist(argvars, retvar)
6813     VAR		argvars;
6814     VAR		retvar;
6815 {
6816     char_u	*r = NULL;
6817 
6818 #ifdef FEAT_CLIENTSERVER
6819 # ifdef WIN32
6820     r = serverGetVimNames();
6821 # else
6822     make_connection();
6823     if (X_DISPLAY != NULL)
6824 	r = serverGetVimNames(X_DISPLAY);
6825 # endif
6826 #endif
6827     retvar->var_type = VAR_STRING;
6828     retvar->var_val.var_string = r;
6829 }
6830 
6831 /*ARGSUSED*/
6832     static void
6833 f_remote_peek(argvars, retvar)
6834     VAR		argvars;
6835     VAR		retvar;
6836 {
6837 #ifdef FEAT_CLIENTSERVER
6838     var		v;
6839     char_u	*s = NULL;
6840 # ifdef WIN32
6841     int		n = 0;
6842 # endif
6843 
6844     if (check_restricted() || check_secure())
6845     {
6846 	retvar->var_val.var_number = -1;
6847 	return;
6848     }
6849 # ifdef WIN32
6850     sscanf(get_var_string(&argvars[0]), "%x", &n);
6851     if (n == 0)
6852 	retvar->var_val.var_number = -1;
6853     else
6854     {
6855 	s = serverGetReply((HWND)n, FALSE, FALSE, FALSE);
6856 	retvar->var_val.var_number = (s != NULL);
6857     }
6858 # else
6859     retvar->var_val.var_number = 0;
6860     if (check_connection() == FAIL)
6861 	return;
6862 
6863     retvar->var_val.var_number = serverPeekReply(X_DISPLAY,
6864 			     serverStrToWin(get_var_string(&argvars[0])), &s);
6865 # endif
6866 
6867     if (argvars[1].var_type != VAR_UNKNOWN && retvar->var_val.var_number > 0)
6868     {
6869 	v.var_type = VAR_STRING;
6870 	v.var_val.var_string = vim_strsave(s);
6871 	set_var(get_var_string(&argvars[1]), &v);
6872     }
6873 #else
6874     retvar->var_val.var_number = -1;
6875 #endif
6876 }
6877 
6878 /*ARGSUSED*/
6879     static void
6880 f_remote_read(argvars, retvar)
6881     VAR		argvars;
6882     VAR		retvar;
6883 {
6884     char_u	*r = NULL;
6885 
6886 #ifdef FEAT_CLIENTSERVER
6887     if (!check_restricted() && !check_secure())
6888     {
6889 # ifdef WIN32
6890 	/* The server's HWND is encoded in the 'id' parameter */
6891 	int		n = 0;
6892 
6893 	sscanf(get_var_string(&argvars[0]), "%x", &n);
6894 	if (n != 0)
6895 	    r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
6896 	if (r == NULL)
6897 # else
6898 	if (check_connection() == FAIL || serverReadReply(X_DISPLAY,
6899 		  serverStrToWin(get_var_string(&argvars[0])), &r, FALSE) < 0)
6900 # endif
6901 	    EMSG(_("E277: Unable to read a server reply"));
6902     }
6903 #endif
6904     retvar->var_type = VAR_STRING;
6905     retvar->var_val.var_string = r;
6906 }
6907 
6908 /*ARGSUSED*/
6909     static void
6910 f_server2client(argvars, retvar)
6911     VAR		argvars;
6912     VAR		retvar;
6913 {
6914 #ifdef FEAT_CLIENTSERVER
6915     char_u	buf[NUMBUFLEN];
6916     char_u	*server = get_var_string(&argvars[0]);
6917     char_u	*reply = get_var_string_buf(&argvars[1], buf);
6918 
6919     retvar->var_val.var_number = -1;
6920     if (check_restricted() || check_secure())
6921 	return;
6922 # ifdef FEAT_X11
6923     if (check_connection() == FAIL)
6924 	return;
6925 # endif
6926 
6927     if (serverSendReply(server, reply) < 0)
6928     {
6929 	EMSG(_("E258: Unable to send to client"));
6930 	return;
6931     }
6932     retvar->var_val.var_number = 0;
6933 #else
6934     retvar->var_val.var_number = -1;
6935 #endif
6936 }
6937 
6938 #ifdef FEAT_CLIENTSERVER
6939 static void remote_common __ARGS((VAR argvars, VAR retvar, int expr));
6940 
6941     static void
6942 remote_common(argvars, retvar, expr)
6943     VAR		argvars;
6944     VAR		retvar;
6945     int		expr;
6946 {
6947     char_u	*server_name;
6948     char_u	*keys;
6949     char_u	*r = NULL;
6950     char_u	buf[NUMBUFLEN];
6951 # ifdef WIN32
6952     HWND	w;
6953 # else
6954     Window	w;
6955 # endif
6956 
6957     if (check_restricted() || check_secure())
6958 	return;
6959 
6960 # ifdef FEAT_X11
6961     if (check_connection() == FAIL)
6962 	return;
6963 # endif
6964 
6965     server_name = get_var_string(&argvars[0]);
6966     keys = get_var_string_buf(&argvars[1], buf);
6967 # ifdef WIN32
6968     if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0)
6969 # else
6970     if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE)
6971 									  < 0)
6972 # endif
6973     {
6974 	if (r != NULL)
6975 	    EMSG(r);		/* sending worked but evaluation failed */
6976 	else
6977 	    EMSG2(_("E241: Unable to send to %s"), server_name);
6978 	return;
6979     }
6980 
6981     retvar->var_val.var_string = r;
6982 
6983     if (argvars[2].var_type != VAR_UNKNOWN)
6984     {
6985 	var	v;
6986 	char_u	str[30];
6987 
6988 	sprintf((char *)str, "0x%x", (unsigned int)w);
6989 	v.var_type = VAR_STRING;
6990 	v.var_val.var_string = vim_strsave(str);
6991 	set_var(get_var_string(&argvars[2]), &v);
6992     }
6993 }
6994 #endif
6995 
6996 /*
6997  * "remote_expr()" function
6998  */
6999 /*ARGSUSED*/
7000     static void
7001 f_remote_expr(argvars, retvar)
7002     VAR		argvars;
7003     VAR		retvar;
7004 {
7005     retvar->var_type = VAR_STRING;
7006     retvar->var_val.var_string = NULL;
7007 #ifdef FEAT_CLIENTSERVER
7008     remote_common(argvars, retvar, TRUE);
7009 #endif
7010 }
7011 
7012 /*
7013  * "remote_send()" function
7014  */
7015 /*ARGSUSED*/
7016     static void
7017 f_remote_send(argvars, retvar)
7018     VAR		argvars;
7019     VAR		retvar;
7020 {
7021     retvar->var_type = VAR_STRING;
7022     retvar->var_val.var_string = NULL;
7023 #ifdef FEAT_CLIENTSERVER
7024     remote_common(argvars, retvar, FALSE);
7025 #endif
7026 }
7027 
7028 /*
7029  * "remote_foreground()" function
7030  */
7031 /*ARGSUSED*/
7032     static void
7033 f_remote_foreground(argvars, retvar)
7034     VAR		argvars;
7035     VAR		retvar;
7036 {
7037     retvar->var_val.var_number = 0;
7038 #ifdef FEAT_CLIENTSERVER
7039 # ifdef WIN32
7040     /* On Win32 it's done in this application. */
7041     serverForeground(get_var_string(&argvars[0]));
7042 # else
7043     /* Send a foreground() expression to the server. */
7044     argvars[1].var_type = VAR_STRING;
7045     argvars[1].var_val.var_string = vim_strsave((char_u *)"foreground()");
7046     argvars[2].var_type = VAR_UNKNOWN;
7047     remote_common(argvars, retvar, TRUE);
7048     vim_free(argvars[1].var_val.var_string);
7049 # endif
7050 #endif
7051 }
7052 
7053 /*
7054  * "repeat()" function
7055  */
7056 /*ARGSUSED*/
7057     static void
7058 f_repeat(argvars, retvar)
7059     VAR		argvars;
7060     VAR		retvar;
7061 {
7062     char_u	*p;
7063     int		n;
7064     int		slen;
7065     int		len;
7066     char_u	*r;
7067     int		i;
7068 
7069     p = get_var_string(&argvars[0]);
7070     n = get_var_number(&argvars[1]);
7071 
7072     retvar->var_type = VAR_STRING;
7073     retvar->var_val.var_string = NULL;
7074 
7075     slen = (int)STRLEN(p);
7076     len = slen * n;
7077 
7078     if (len <= 0)
7079         return;
7080 
7081     r = alloc(len + 1);
7082     if (r != NULL)
7083     {
7084         for (i = 0; i < n; i++)
7085 	    mch_memmove(r + i * slen, p, (size_t)slen);
7086         r[len] = NUL;
7087     }
7088 
7089     retvar->var_val.var_string = r;
7090 }
7091 
7092 #ifdef HAVE_STRFTIME
7093 /*
7094  * "strftime({format}[, {time}])" function
7095  */
7096     static void
7097 f_strftime(argvars, retvar)
7098     VAR		argvars;
7099     VAR		retvar;
7100 {
7101     char_u	result_buf[256];
7102     struct tm	*curtime;
7103     time_t	seconds;
7104     char_u	*p;
7105 
7106     retvar->var_type = VAR_STRING;
7107 
7108     p = get_var_string(&argvars[0]);
7109     if (argvars[1].var_type == VAR_UNKNOWN)
7110 	seconds = time(NULL);
7111     else
7112 	seconds = (time_t)get_var_number(&argvars[1]);
7113     curtime = localtime(&seconds);
7114     /* MSVC returns NULL for an invalid value of seconds. */
7115     if (curtime == NULL)
7116 	retvar->var_val.var_string = vim_strsave((char_u *)_("(Invalid)"));
7117     else
7118     {
7119 # ifdef FEAT_MBYTE
7120 	vimconv_T   conv;
7121 	char_u	    *enc;
7122 
7123 	conv.vc_type = CONV_NONE;
7124 	enc = enc_locale();
7125 	convert_setup(&conv, p_enc, enc);
7126 	if (conv.vc_type != CONV_NONE)
7127 	    p = string_convert(&conv, p, NULL);
7128 # endif
7129 	if (p != NULL)
7130 	    (void)strftime((char *)result_buf, sizeof(result_buf),
7131 							  (char *)p, curtime);
7132 	else
7133 	    result_buf[0] = NUL;
7134 
7135 # ifdef FEAT_MBYTE
7136 	if (conv.vc_type != CONV_NONE)
7137 	    vim_free(p);
7138 	convert_setup(&conv, enc, p_enc);
7139 	if (conv.vc_type != CONV_NONE)
7140 	    retvar->var_val.var_string =
7141 				      string_convert(&conv, result_buf, NULL);
7142 	else
7143 # endif
7144 	    retvar->var_val.var_string = vim_strsave(result_buf);
7145 
7146 # ifdef FEAT_MBYTE
7147 	/* Release conversion descriptors */
7148 	convert_setup(&conv, NULL, NULL);
7149 	vim_free(enc);
7150 # endif
7151     }
7152 }
7153 #endif
7154 
7155 /*
7156  * "stridx()" function
7157  */
7158     static void
7159 f_stridx(argvars, retvar)
7160     VAR		argvars;
7161     VAR		retvar;
7162 {
7163     char_u	buf[NUMBUFLEN];
7164     char_u	*needle;
7165     char_u	*haystack;
7166     char_u	*pos;
7167 
7168     needle = get_var_string(&argvars[1]);
7169     haystack = get_var_string_buf(&argvars[0], buf);
7170     pos	= (char_u *)strstr((char *)haystack, (char *)needle);
7171 
7172     if (pos == NULL)
7173 	retvar->var_val.var_number = -1;
7174     else
7175 	retvar->var_val.var_number = (varnumber_T) (pos - haystack);
7176 }
7177 
7178 /*
7179  * "strridx()" function
7180  */
7181     static void
7182 f_strridx(argvars, retvar)
7183     VAR		argvars;
7184     VAR		retvar;
7185 {
7186     char_u	buf[NUMBUFLEN];
7187     char_u	*needle;
7188     char_u	*haystack;
7189     char_u	*rest;
7190     char_u	*lastmatch = NULL;
7191 
7192     needle = get_var_string(&argvars[1]);
7193     haystack = get_var_string_buf(&argvars[0], buf);
7194     rest = haystack;
7195     while (*haystack != '\0')
7196     {
7197 	rest = (char_u *)strstr((char *)rest, (char *)needle);
7198 	if (rest == NULL)
7199 	    break;
7200 	lastmatch = rest++;
7201     }
7202 
7203     if (lastmatch == NULL)
7204 	retvar->var_val.var_number = -1;
7205     else
7206 	retvar->var_val.var_number = (varnumber_T) (lastmatch - haystack);
7207 }
7208 
7209 /*
7210  * "strlen()" function
7211  */
7212     static void
7213 f_strlen(argvars, retvar)
7214     VAR		argvars;
7215     VAR		retvar;
7216 {
7217     retvar->var_val.var_number = (varnumber_T) (STRLEN(get_var_string(&argvars[0])));
7218 }
7219 
7220 /*
7221  * "strpart()" function
7222  */
7223     static void
7224 f_strpart(argvars, retvar)
7225     VAR		argvars;
7226     VAR		retvar;
7227 {
7228     char_u	*p;
7229     int		n;
7230     int		len;
7231     int		slen;
7232 
7233     p = get_var_string(&argvars[0]);
7234     slen = (int)STRLEN(p);
7235 
7236     n = get_var_number(&argvars[1]);
7237     if (argvars[2].var_type != VAR_UNKNOWN)
7238 	len = get_var_number(&argvars[2]);
7239     else
7240 	len = slen - n;	    /* default len: all bytes that are available. */
7241 
7242     /*
7243      * Only return the overlap between the specified part and the actual
7244      * string.
7245      */
7246     if (n < 0)
7247     {
7248 	len += n;
7249 	n = 0;
7250     }
7251     else if (n > slen)
7252 	n = slen;
7253     if (len < 0)
7254 	len = 0;
7255     else if (n + len > slen)
7256 	len = slen - n;
7257 
7258     retvar->var_type = VAR_STRING;
7259     retvar->var_val.var_string = vim_strnsave(p + n, len);
7260 }
7261 
7262 /*
7263  * "strtrans()" function
7264  */
7265     static void
7266 f_strtrans(argvars, retvar)
7267     VAR		argvars;
7268     VAR		retvar;
7269 {
7270     retvar->var_type = VAR_STRING;
7271     retvar->var_val.var_string = transstr(get_var_string(&argvars[0]));
7272 }
7273 
7274 /*
7275  * "synID(line, col, trans)" function
7276  */
7277 /*ARGSUSED*/
7278     static void
7279 f_synID(argvars, retvar)
7280     VAR		argvars;
7281     VAR		retvar;
7282 {
7283     int		id = 0;
7284 #ifdef FEAT_SYN_HL
7285     long	line;
7286     long	col;
7287     int		trans;
7288 
7289     line = get_var_lnum(argvars);
7290     col = get_var_number(&argvars[1]) - 1;
7291     trans = get_var_number(&argvars[2]);
7292 
7293     if (line >= 1 && line <= curbuf->b_ml.ml_line_count
7294 	    && col >= 0 && col < (long)STRLEN(ml_get(line)))
7295 	id = syn_get_id(line, col, trans);
7296 #endif
7297 
7298     retvar->var_val.var_number = id;
7299 }
7300 
7301 /*
7302  * "synIDattr(id, what [, mode])" function
7303  */
7304 /*ARGSUSED*/
7305     static void
7306 f_synIDattr(argvars, retvar)
7307     VAR		argvars;
7308     VAR		retvar;
7309 {
7310     char_u	*p = NULL;
7311 #ifdef FEAT_SYN_HL
7312     int		id;
7313     char_u	*what;
7314     char_u	*mode;
7315     char_u	modebuf[NUMBUFLEN];
7316     int		modec;
7317 
7318     id = get_var_number(&argvars[0]);
7319     what = get_var_string(&argvars[1]);
7320     if (argvars[2].var_type != VAR_UNKNOWN)
7321     {
7322 	mode = get_var_string_buf(&argvars[2], modebuf);
7323 	modec = TOLOWER_ASC(mode[0]);
7324 	if (modec != 't' && modec != 'c'
7325 #ifdef FEAT_GUI
7326 		&& modec != 'g'
7327 #endif
7328 		)
7329 	    modec = 0;	/* replace invalid with current */
7330     }
7331     else
7332     {
7333 #ifdef FEAT_GUI
7334 	if (gui.in_use)
7335 	    modec = 'g';
7336 	else
7337 #endif
7338 	    if (t_colors > 1)
7339 	    modec = 'c';
7340 	else
7341 	    modec = 't';
7342     }
7343 
7344 
7345     switch (TOLOWER_ASC(what[0]))
7346     {
7347 	case 'b':
7348 		if (TOLOWER_ASC(what[1]) == 'g')	/* bg[#] */
7349 		    p = highlight_color(id, what, modec);
7350 		else					/* bold */
7351 		    p = highlight_has_attr(id, HL_BOLD, modec);
7352 		break;
7353 
7354 	case 'f':					/* fg[#] */
7355 		p = highlight_color(id, what, modec);
7356 		break;
7357 
7358 	case 'i':
7359 		if (TOLOWER_ASC(what[1]) == 'n')	/* inverse */
7360 		    p = highlight_has_attr(id, HL_INVERSE, modec);
7361 		else					/* italic */
7362 		    p = highlight_has_attr(id, HL_ITALIC, modec);
7363 		break;
7364 
7365 	case 'n':					/* name */
7366 		p = get_highlight_name(NULL, id - 1);
7367 		break;
7368 
7369 	case 'r':					/* reverse */
7370 		p = highlight_has_attr(id, HL_INVERSE, modec);
7371 		break;
7372 
7373 	case 's':					/* standout */
7374 		p = highlight_has_attr(id, HL_STANDOUT, modec);
7375 		break;
7376 
7377 	case 'u':					/* underline */
7378 		p = highlight_has_attr(id, HL_UNDERLINE, modec);
7379 		break;
7380     }
7381 
7382     if (p != NULL)
7383 	p = vim_strsave(p);
7384 #endif
7385     retvar->var_type = VAR_STRING;
7386     retvar->var_val.var_string = p;
7387 }
7388 
7389 /*
7390  * "synIDtrans(id)" function
7391  */
7392 /*ARGSUSED*/
7393     static void
7394 f_synIDtrans(argvars, retvar)
7395     VAR		argvars;
7396     VAR		retvar;
7397 {
7398     int		id;
7399 
7400 #ifdef FEAT_SYN_HL
7401     id = get_var_number(&argvars[0]);
7402 
7403     if (id > 0)
7404 	id = syn_get_final_id(id);
7405     else
7406 #endif
7407 	id = 0;
7408 
7409     retvar->var_val.var_number = id;
7410 }
7411 
7412 /*
7413  * "system()" function
7414  */
7415     static void
7416 f_system(argvars, retvar)
7417     VAR		argvars;
7418     VAR		retvar;
7419 {
7420     char_u	*p;
7421 
7422     p = get_cmd_output(get_var_string(&argvars[0]), SHELL_SILENT);
7423 #ifdef USE_CR
7424     /* translate <CR> into <NL> */
7425     if (p != NULL)
7426     {
7427 	char_u	*s;
7428 
7429 	for (s = p; *s; ++s)
7430 	{
7431 	    if (*s == CAR)
7432 		*s = NL;
7433 	}
7434     }
7435 #else
7436 # ifdef USE_CRNL
7437     /* translate <CR><NL> into <NL> */
7438     if (p != NULL)
7439     {
7440 	char_u	*s, *d;
7441 
7442 	d = p;
7443 	for (s = p; *s; ++s)
7444 	{
7445 	    if (s[0] == CAR && s[1] == NL)
7446 		++s;
7447 	    *d++ = *s;
7448 	}
7449 	*d = NUL;
7450     }
7451 # endif
7452 #endif
7453     retvar->var_type = VAR_STRING;
7454     retvar->var_val.var_string = p;
7455 }
7456 
7457 /*
7458  * "submatch()" function
7459  */
7460     static void
7461 f_submatch(argvars, retvar)
7462     VAR		argvars;
7463     VAR		retvar;
7464 {
7465     retvar->var_type = VAR_STRING;
7466     retvar->var_val.var_string = reg_submatch((int)get_var_number(&argvars[0]));
7467 }
7468 
7469 /*
7470  * "substitute()" function
7471  */
7472     static void
7473 f_substitute(argvars, retvar)
7474     VAR		argvars;
7475     VAR		retvar;
7476 {
7477     char_u	patbuf[NUMBUFLEN];
7478     char_u	subbuf[NUMBUFLEN];
7479     char_u	flagsbuf[NUMBUFLEN];
7480 
7481     retvar->var_type = VAR_STRING;
7482     retvar->var_val.var_string = do_string_sub(
7483 	    get_var_string(&argvars[0]),
7484 	    get_var_string_buf(&argvars[1], patbuf),
7485 	    get_var_string_buf(&argvars[2], subbuf),
7486 	    get_var_string_buf(&argvars[3], flagsbuf));
7487 }
7488 
7489 /*
7490  * "tempname()" function
7491  */
7492 /*ARGSUSED*/
7493     static void
7494 f_tempname(argvars, retvar)
7495     VAR		argvars;
7496     VAR		retvar;
7497 {
7498     static int	x = 'A';
7499 
7500     retvar->var_type = VAR_STRING;
7501     retvar->var_val.var_string = vim_tempname(x);
7502 
7503     /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different
7504      * names.  Skip 'I' and 'O', they are used for shell redirection. */
7505     do
7506     {
7507 	if (x == 'Z')
7508 	    x = '0';
7509 	else if (x == '9')
7510 	    x = 'A';
7511 	else
7512 	{
7513 #ifdef EBCDIC
7514 	    if (x == 'I')
7515 		x = 'J';
7516 	    else if (x == 'R')
7517 		x = 'S';
7518 	    else
7519 #endif
7520 		++x;
7521 	}
7522     } while (x == 'I' || x == 'O');
7523 }
7524 
7525 /*
7526  * "tolower(string)" function
7527  */
7528     static void
7529 f_tolower(argvars, retvar)
7530     VAR		argvars;
7531     VAR		retvar;
7532 {
7533     char_u	*p;
7534 
7535     p = vim_strsave(get_var_string(&argvars[0]));
7536     retvar->var_type = VAR_STRING;
7537     retvar->var_val.var_string = p;
7538 
7539     if (p != NULL)
7540 	while (*p != NUL)
7541 	{
7542 #ifdef FEAT_MBYTE
7543 	    int		l;
7544 
7545 	    if (enc_utf8)
7546 	    {
7547 		int c, lc;
7548 
7549 		c = utf_ptr2char(p);
7550 		lc = utf_tolower(c);
7551 		l = utf_ptr2len_check(p);
7552 		/* TODO: reallocate string when byte count changes. */
7553 		if (utf_char2len(lc) == l)
7554 		    utf_char2bytes(lc, p);
7555 		p += l;
7556 	    }
7557 	    else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
7558 		p += l;		/* skip multi-byte character */
7559 	    else
7560 #endif
7561 	    {
7562 		*p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
7563 		++p;
7564 	    }
7565 	}
7566 }
7567 
7568 /*
7569  * "toupper(string)" function
7570  */
7571     static void
7572 f_toupper(argvars, retvar)
7573     VAR		argvars;
7574     VAR		retvar;
7575 {
7576     char_u	*p;
7577 
7578     p = vim_strsave(get_var_string(&argvars[0]));
7579     retvar->var_type = VAR_STRING;
7580     retvar->var_val.var_string = p;
7581 
7582     if (p != NULL)
7583 	while (*p != NUL)
7584 	{
7585 #ifdef FEAT_MBYTE
7586 	    int		l;
7587 
7588 	    if (enc_utf8)
7589 	    {
7590 		int c, uc;
7591 
7592 		c = utf_ptr2char(p);
7593 		uc = utf_toupper(c);
7594 		l = utf_ptr2len_check(p);
7595 		/* TODO: reallocate string when byte count changes. */
7596 		if (utf_char2len(uc) == l)
7597 		    utf_char2bytes(uc, p);
7598 		p += l;
7599 	    }
7600 	    else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
7601 		p += l;		/* skip multi-byte character */
7602 	    else
7603 #endif
7604 	    {
7605 		*p = TOUPPER_LOC(*p); /* note that toupper() can be a macro */
7606 		p++;
7607 	    }
7608 	}
7609 }
7610 
7611 /*
7612  * "tr(string, fromstr, tostr)" function
7613  */
7614     static void
7615 f_tr(argvars, retvar)
7616     VAR		argvars;
7617     VAR		retvar;
7618 {
7619     char_u	*instr;
7620     char_u	*fromstr;
7621     char_u	*tostr;
7622     char_u	*p;
7623 #ifdef FEAT_MBYTE
7624     int	        inlen;
7625     int	        fromlen;
7626     int	        tolen;
7627     int		idx;
7628     char_u	*cpstr;
7629     int		cplen;
7630     int		first = TRUE;
7631 #endif
7632     char_u	buf[NUMBUFLEN];
7633     char_u	buf2[NUMBUFLEN];
7634     garray_T	ga;
7635 
7636     instr = get_var_string(&argvars[0]);
7637     fromstr = get_var_string_buf(&argvars[1], buf);
7638     tostr = get_var_string_buf(&argvars[2], buf2);
7639 
7640     /* Default return value: empty string. */
7641     retvar->var_type = VAR_STRING;
7642     retvar->var_val.var_string = NULL;
7643     ga_init2(&ga, (int)sizeof(char), 80);
7644 
7645 #ifdef FEAT_MBYTE
7646     if (!has_mbyte)
7647 #endif
7648 	/* not multi-byte: fromstr and tostr must be the same length */
7649 	if (STRLEN(fromstr) != STRLEN(tostr))
7650 	{
7651 error:
7652 	    EMSG2(_(e_invarg2), fromstr);
7653 	    ga_clear(&ga);
7654 	    return;
7655 	}
7656 
7657     /* fromstr and tostr have to contain the same number of chars */
7658     while (*instr != NUL)
7659     {
7660 #ifdef FEAT_MBYTE
7661 	if (has_mbyte)
7662 	{
7663 	    inlen = mb_ptr2len_check(instr);
7664 	    cpstr = instr;
7665 	    cplen = inlen;
7666 	    idx = 0;
7667 	    for (p = fromstr; *p != NUL; p += fromlen)
7668 	    {
7669 		fromlen = mb_ptr2len_check(p);
7670 		if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0)
7671 		{
7672 		    for (p = tostr; *p != NUL; p += tolen)
7673 		    {
7674 			tolen = mb_ptr2len_check(p);
7675 			if (idx-- == 0)
7676 			{
7677 			    cplen = tolen;
7678 			    cpstr = p;
7679 			    break;
7680 			}
7681 		    }
7682 		    if (*p == NUL)	/* tostr is shorter than fromstr */
7683 			goto error;
7684 		    break;
7685 		}
7686 		++idx;
7687 	    }
7688 
7689 	    if (first && cpstr == instr)
7690 	    {
7691 		/* Check that fromstr and tostr have the same number of
7692 		 * (multi-byte) characters.  Done only once when a character
7693 		 * of instr doesn't appear in fromstr. */
7694 		first = FALSE;
7695 		for (p = tostr; *p != NUL; p += tolen)
7696 		{
7697 		    tolen = mb_ptr2len_check(p);
7698 		    --idx;
7699 		}
7700 		if (idx != 0)
7701 		    goto error;
7702 	    }
7703 
7704 	    ga_grow(&ga, cplen);
7705 	    mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen);
7706 	    ga.ga_len += cplen;
7707 	    ga.ga_room -= cplen;
7708 
7709 	    instr += inlen;
7710 	}
7711 	else
7712 #endif
7713 	{
7714 	    /* When not using multi-byte chars we can do it faster. */
7715 	    p = vim_strchr(fromstr, *instr);
7716 	    if (p != NULL)
7717 		ga_append(&ga, tostr[p - fromstr]);
7718 	    else
7719 		ga_append(&ga, *instr);
7720 	    ++instr;
7721 	}
7722     }
7723 
7724     retvar->var_val.var_string = ga.ga_data;
7725 }
7726 
7727 /*
7728  * "type(expr)" function
7729  */
7730     static void
7731 f_type(argvars, retvar)
7732     VAR		argvars;
7733     VAR		retvar;
7734 {
7735     if (argvars[0].var_type == VAR_NUMBER)
7736 	retvar->var_val.var_number = 0;
7737     else
7738 	retvar->var_val.var_number = 1;
7739 }
7740 
7741 /*
7742  * "virtcol(string)" function
7743  */
7744     static void
7745 f_virtcol(argvars, retvar)
7746     VAR		argvars;
7747     VAR		retvar;
7748 {
7749     colnr_T	vcol = 0;
7750     pos_T	*fp;
7751 
7752     fp = var2fpos(&argvars[0], FALSE);
7753     if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count)
7754     {
7755 	getvvcol(curwin, fp, NULL, NULL, &vcol);
7756 	++vcol;
7757     }
7758 
7759     retvar->var_val.var_number = vcol;
7760 }
7761 
7762 /*
7763  * "visualmode()" function
7764  */
7765 /*ARGSUSED*/
7766     static void
7767 f_visualmode(argvars, retvar)
7768     VAR		argvars;
7769     VAR		retvar;
7770 {
7771 #ifdef FEAT_VISUAL
7772     char_u	str[2];
7773 
7774     retvar->var_type = VAR_STRING;
7775     str[0] = curbuf->b_visual_mode_eval;
7776     str[1] = NUL;
7777     retvar->var_val.var_string = vim_strsave(str);
7778 
7779     /* A non-zero number or non-empty string argument: reset mode. */
7780     if ((argvars[0].var_type == VAR_NUMBER
7781 		&& argvars[0].var_val.var_number != 0)
7782 	    || (argvars[0].var_type == VAR_STRING
7783 		&& *get_var_string(&argvars[0]) != NUL))
7784 	curbuf->b_visual_mode_eval = NUL;
7785 #else
7786     retvar->var_val.var_number = 0; /* return anything, it won't work anyway */
7787 #endif
7788 }
7789 
7790 /*
7791  * "winbufnr(nr)" function
7792  */
7793     static void
7794 f_winbufnr(argvars, retvar)
7795     VAR		argvars;
7796     VAR		retvar;
7797 {
7798     win_T	*wp;
7799 
7800     wp = find_win_by_nr(&argvars[0]);
7801     if (wp == NULL)
7802 	retvar->var_val.var_number = -1;
7803     else
7804 	retvar->var_val.var_number = wp->w_buffer->b_fnum;
7805 }
7806 
7807 /*
7808  * "wincol()" function
7809  */
7810 /*ARGSUSED*/
7811     static void
7812 f_wincol(argvars, retvar)
7813     VAR		argvars;
7814     VAR		retvar;
7815 {
7816     validate_cursor();
7817     retvar->var_val.var_number = curwin->w_wcol + 1;
7818 }
7819 
7820 /*
7821  * "winheight(nr)" function
7822  */
7823     static void
7824 f_winheight(argvars, retvar)
7825     VAR		argvars;
7826     VAR		retvar;
7827 {
7828     win_T	*wp;
7829 
7830     wp = find_win_by_nr(&argvars[0]);
7831     if (wp == NULL)
7832 	retvar->var_val.var_number = -1;
7833     else
7834 	retvar->var_val.var_number = wp->w_height;
7835 }
7836 
7837 /*
7838  * "winline()" function
7839  */
7840 /*ARGSUSED*/
7841     static void
7842 f_winline(argvars, retvar)
7843     VAR		argvars;
7844     VAR		retvar;
7845 {
7846     validate_cursor();
7847     retvar->var_val.var_number = curwin->w_wrow + 1;
7848 }
7849 
7850 /*
7851  * "winnr()" function
7852  */
7853 /* ARGSUSED */
7854     static void
7855 f_winnr(argvars, retvar)
7856     VAR		argvars;
7857     VAR		retvar;
7858 {
7859     int		nr = 1;
7860 #ifdef FEAT_WINDOWS
7861     win_T	*wp;
7862 
7863     for (wp = firstwin; wp != curwin; wp = wp->w_next)
7864 	++nr;
7865 #endif
7866     retvar->var_val.var_number = nr;
7867 }
7868 
7869 /*
7870  * "winrestcmd()" function
7871  */
7872 /* ARGSUSED */
7873     static void
7874 f_winrestcmd(argvars, retvar)
7875     VAR		argvars;
7876     VAR		retvar;
7877 {
7878 #ifdef FEAT_WINDOWS
7879     win_T	*wp;
7880     int		winnr = 1;
7881     garray_T	ga;
7882     char_u	buf[50];
7883 
7884     ga_init2(&ga, (int)sizeof(char), 70);
7885     for (wp = firstwin; wp != NULL; wp = wp->w_next)
7886     {
7887 	sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height);
7888 	ga_concat(&ga, buf);
7889 # ifdef FEAT_VERTSPLIT
7890 	sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width);
7891 	ga_concat(&ga, buf);
7892 # endif
7893 	++winnr;
7894     }
7895 
7896     retvar->var_val.var_string = ga.ga_data;
7897 #else
7898     retvar->var_val.var_string = NULL;
7899 #endif
7900     retvar->var_type = VAR_STRING;
7901 }
7902 
7903 /*
7904  * "winwidth(nr)" function
7905  */
7906     static void
7907 f_winwidth(argvars, retvar)
7908     VAR		argvars;
7909     VAR		retvar;
7910 {
7911     win_T	*wp;
7912 
7913     wp = find_win_by_nr(&argvars[0]);
7914     if (wp == NULL)
7915 	retvar->var_val.var_number = -1;
7916     else
7917 #ifdef FEAT_VERTSPLIT
7918 	retvar->var_val.var_number = wp->w_width;
7919 #else
7920 	retvar->var_val.var_number = Columns;
7921 #endif
7922 }
7923 
7924     static win_T *
7925 find_win_by_nr(vp)
7926     VAR		vp;
7927 {
7928 #ifdef FEAT_WINDOWS
7929     win_T	*wp;
7930 #endif
7931     int		nr;
7932 
7933     nr = get_var_number(vp);
7934 
7935 #ifdef FEAT_WINDOWS
7936     if (nr == 0)
7937 	return curwin;
7938 
7939     for (wp = firstwin; wp != NULL; wp = wp->w_next)
7940 	if (--nr <= 0)
7941 	    break;
7942     return wp;
7943 #else
7944     if (nr == 0 || nr == 1)
7945 	return curwin;
7946     return NULL;
7947 #endif
7948 }
7949 
7950 /*
7951  * Translate a String variable into a position.
7952  */
7953     static pos_T *
7954 var2fpos(varp, lnum)
7955     VAR		varp;
7956     int		lnum;		/* TRUE when $ is last line */
7957 {
7958     char_u	*name;
7959     static pos_T	pos;
7960     pos_T	*pp;
7961 
7962     name = get_var_string(varp);
7963     if (name[0] == '.')		/* cursor */
7964 	return &curwin->w_cursor;
7965     if (name[0] == '\'')	/* mark */
7966     {
7967 	pp = getmark(name[1], FALSE);
7968 	if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
7969 	    return NULL;
7970 	return pp;
7971     }
7972     if (name[0] == '$')		/* last column or line */
7973     {
7974 	if (lnum)
7975 	{
7976 	    pos.lnum = curbuf->b_ml.ml_line_count;
7977 	    pos.col = 0;
7978 	}
7979 	else
7980 	{
7981 	    pos.lnum = curwin->w_cursor.lnum;
7982 	    pos.col = (colnr_T)STRLEN(ml_get_curline());
7983 	}
7984 	return &pos;
7985     }
7986     return NULL;
7987 }
7988 
7989 /*
7990  * Get the length of an environment variable name.
7991  * Advance "arg" to the first character after the name.
7992  * Return 0 for error.
7993  */
7994     static int
7995 get_env_len(arg)
7996     char_u	**arg;
7997 {
7998     char_u	*p;
7999     int		len;
8000 
8001     for (p = *arg; vim_isIDc(*p); ++p)
8002 	;
8003     if (p == *arg)	    /* no name found */
8004 	return 0;
8005 
8006     len = (int)(p - *arg);
8007     *arg = p;
8008     return len;
8009 }
8010 
8011 /*
8012  * Get the length of the name of a function or internal variable.
8013  * "arg" is advanced to the first non-white character after the name.
8014  * Return 0 if something is wrong.
8015  */
8016     static int
8017 get_id_len(arg)
8018     char_u	**arg;
8019 {
8020     char_u	*p;
8021     int		len;
8022 
8023     /* Find the end of the name. */
8024     for (p = *arg; eval_isnamec(*p); ++p)
8025 	;
8026     if (p == *arg)	    /* no name found */
8027 	return 0;
8028 
8029     len = (int)(p - *arg);
8030     *arg = skipwhite(p);
8031 
8032     return len;
8033 }
8034 
8035 /*
8036  * Get the length of the name of a function.
8037  * "arg" is advanced to the first non-white character after the name.
8038  * Return 0 if something is wrong.
8039  * If the name contains 'magic' {}'s, expand them and return the
8040  * expanded name in an allocated string via 'alias' - caller must free.
8041  */
8042     static int
8043 get_func_len(arg, alias, evaluate)
8044     char_u	**arg;
8045     char_u	**alias;
8046     int		evaluate;
8047 {
8048     int		len;
8049 #ifdef FEAT_MAGIC_BRACES
8050     char_u	*p;
8051     char_u	*expr_start;
8052     char_u	*expr_end;
8053 #endif
8054 
8055     *alias = NULL;  /* default to no alias */
8056 
8057     if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
8058 						  && (*arg)[2] == (int)KE_SNR)
8059     {
8060 	/* hard coded <SNR>, already translated */
8061 	*arg += 3;
8062 	return get_id_len(arg) + 3;
8063     }
8064     len = eval_fname_script(*arg);
8065     if (len > 0)
8066     {
8067 	/* literal "<SID>", "s:" or "<SNR>" */
8068 	*arg += len;
8069     }
8070 
8071 #ifdef FEAT_MAGIC_BRACES
8072     /*
8073      * Find the end of the name;
8074      */
8075     p = find_name_end(*arg, &expr_start, &expr_end);
8076     /* check for {} construction */
8077     if (expr_start != NULL)
8078     {
8079 	char_u	*temp_string;
8080 
8081 	if (!evaluate)
8082 	{
8083 	    len += (int)(p - *arg);
8084 	    *arg = skipwhite(p);
8085 	    return len;
8086 	}
8087 
8088 	/*
8089 	 * Include any <SID> etc in the expanded string:
8090 	 * Thus the -len here.
8091 	 */
8092 	temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
8093 	if (temp_string == NULL)
8094 	    return 0;
8095 	*alias = temp_string;
8096 	*arg = skipwhite(p);
8097 	return (int)STRLEN(temp_string);
8098     }
8099 #endif
8100 
8101     len += get_id_len(arg);
8102     if (len == 0)
8103 	EMSG2(_(e_invexpr2), *arg);
8104 
8105     return len;
8106 }
8107 
8108     static char_u *
8109 find_name_end(arg, expr_start, expr_end)
8110     char_u	*arg;
8111     char_u	**expr_start;
8112     char_u	**expr_end;
8113 {
8114     int		nesting = 0;
8115     char_u	*p;
8116 
8117     *expr_start = NULL;
8118     *expr_end = NULL;
8119 
8120     for (p = arg; (*p != NUL && (eval_isnamec(*p) || nesting != 0)); ++p)
8121     {
8122 #ifdef FEAT_MAGIC_BRACES
8123 	if (*p == '{')
8124 	{
8125 	    nesting++;
8126 	    if (*expr_start == NULL)
8127 		*expr_start = p;
8128 	}
8129 	else if (*p == '}')
8130 	{
8131 	    nesting--;
8132 	    if (nesting == 0 && *expr_end == NULL)
8133 		*expr_end = p;
8134 	}
8135 #endif
8136     }
8137 
8138     return p;
8139 }
8140 
8141 /*
8142  * Return TRUE if character "c" can be used in a variable or function name.
8143  */
8144     static int
8145 eval_isnamec(c)
8146     int	    c;
8147 {
8148     return (ASCII_ISALNUM(c) || c == '_' || c == ':'
8149 #ifdef FEAT_MAGIC_BRACES
8150 	    || c == '{' || c == '}'
8151 #endif
8152 	    );
8153 }
8154 
8155 /*
8156  * Find a v: variable.
8157  * Return it's index, or -1 if not found.
8158  */
8159     static int
8160 find_vim_var(name, len)
8161     char_u	*name;
8162     int		len;		/* length of "name" */
8163 {
8164     char_u	*vname;
8165     int		vlen;
8166     int		i;
8167 
8168     /*
8169      * Ignore "v:" for old built-in variables, require it for new ones.
8170      */
8171     if (name[0] == 'v' && name[1] == ':')
8172     {
8173 	vname = name + 2;
8174 	vlen = len - 2;
8175     }
8176     else
8177     {
8178 	vname = name;
8179 	vlen = len;
8180     }
8181     for (i = 0; i < VV_LEN; ++i)
8182 	if (vlen == vimvars[i].len && STRCMP(vname, vimvars[i].name) == 0
8183 			 && ((vimvars[i].flags & VV_COMPAT) || vname != name))
8184 	    return i;
8185     return -1;
8186 }
8187 
8188 /*
8189  * Set number v: variable to "val".
8190  */
8191     void
8192 set_vim_var_nr(idx, val)
8193     int		idx;
8194     long	val;
8195 {
8196     vimvars[idx].val = (char_u *)val;
8197 }
8198 
8199 /*
8200  * Get number v: variable value;
8201  */
8202     long
8203 get_vim_var_nr(idx)
8204     int		idx;
8205 {
8206     return (long)vimvars[idx].val;
8207 }
8208 
8209 /*
8210  * Set v:count, v:count1 and v:prevcount.
8211  */
8212     void
8213 set_vcount(count, count1)
8214     long	count;
8215     long	count1;
8216 {
8217     vimvars[VV_PREVCOUNT].val = vimvars[VV_COUNT].val;
8218     vimvars[VV_COUNT].val = (char_u *)count;
8219     vimvars[VV_COUNT1].val = (char_u *)count1;
8220 }
8221 
8222 /*
8223  * Set string v: variable to a copy of "val".
8224  */
8225     void
8226 set_vim_var_string(idx, val, len)
8227     int		idx;
8228     char_u	*val;
8229     int		len;	    /* length of "val" to use or -1 (whole string) */
8230 {
8231     vim_free(vimvars[idx].val);
8232     if (val == NULL)
8233 	vimvars[idx].val = NULL;
8234     else if (len == -1)
8235 	vimvars[idx].val = vim_strsave(val);
8236     else
8237 	vimvars[idx].val = vim_strnsave(val, len);
8238 }
8239 
8240 /*
8241  * Set v:register if needed.
8242  */
8243     void
8244 set_reg_var(c)
8245     int		c;
8246 {
8247     char_u	regname;
8248 
8249     if (c == 0 || c == ' ')
8250 	regname = '"';
8251     else
8252 	regname = c;
8253     /* Avoid free/alloc when the value is already right. */
8254     if (vimvars[VV_REG].val == NULL || vimvars[VV_REG].val[0] != c)
8255 	set_vim_var_string(VV_REG, &regname, 1);
8256 }
8257 
8258 /*
8259  * Get or set v:exception.  If "oldval" == NULL, return the current value.
8260  * Otherwise, restore the value to "oldval" and return NULL.
8261  * Must always be called in pairs to save and restore v:exception!  Does not
8262  * take care of memory allocations.
8263  */
8264     char_u *
8265 v_exception(oldval)
8266     char_u	*oldval;
8267 {
8268     if (oldval == NULL)
8269 	return vimvars[VV_EXCEPTION].val;
8270 
8271     vimvars[VV_EXCEPTION].val = oldval;
8272     return NULL;
8273 }
8274 
8275 /*
8276  * Get or set v:throwpoint.  If "oldval" == NULL, return the current value.
8277  * Otherwise, restore the value to "oldval" and return NULL.
8278  * Must always be called in pairs to save and restore v:throwpoint!  Does not
8279  * take care of memory allocations.
8280  */
8281     char_u *
8282 v_throwpoint(oldval)
8283     char_u	*oldval;
8284 {
8285     if (oldval == NULL)
8286 	return vimvars[VV_THROWPOINT].val;
8287 
8288     vimvars[VV_THROWPOINT].val = oldval;
8289     return NULL;
8290 }
8291 
8292 #if defined(FEAT_AUTOCMD) || defined(PROTO)
8293 /*
8294  * Set v:cmdarg.
8295  * If "eap" != NULL, use "eap" to generate the value and return the old value.
8296  * If "oldarg" != NULL, restore the value to "oldarg" and return NULL.
8297  * Must always be called in pairs!
8298  */
8299     char_u *
8300 set_cmdarg(eap, oldarg)
8301     exarg_T	*eap;
8302     char_u	*oldarg;
8303 {
8304     char_u	*oldval;
8305     char_u	*newval;
8306     unsigned	len;
8307 
8308     oldval = vimvars[VV_CMDARG].val;
8309     if (eap != NULL)
8310     {
8311 	if (eap->force_bin == FORCE_BIN)
8312 	    len = 6;
8313 	else if (eap->force_bin == FORCE_NOBIN)
8314 	    len = 8;
8315 	else
8316 	    len = 0;
8317 	if (eap->force_ff != 0)
8318 	    len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
8319 # ifdef FEAT_MBYTE
8320 	if (eap->force_enc != 0)
8321 	    len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
8322 # endif
8323 
8324 	newval = alloc(len + 1);
8325 	if (newval == NULL)
8326 	    return NULL;
8327 
8328 	if (eap->force_bin == FORCE_BIN)
8329 	    sprintf((char *)newval, " ++bin");
8330 	else if (eap->force_bin == FORCE_NOBIN)
8331 	    sprintf((char *)newval, " ++nobin");
8332 	else
8333 	    *newval = NUL;
8334 	if (eap->force_ff != 0)
8335 	    sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
8336 						    eap->cmd + eap->force_ff);
8337 # ifdef FEAT_MBYTE
8338 	if (eap->force_enc != 0)
8339 	    sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
8340 						   eap->cmd + eap->force_enc);
8341 # endif
8342 	vimvars[VV_CMDARG].val = newval;
8343 	return oldval;
8344     }
8345 
8346     vim_free(oldval);
8347     vimvars[VV_CMDARG].val = oldarg;
8348     return NULL;
8349 }
8350 #endif
8351 
8352 /*
8353  * Get the value of internal variable "name".
8354  * Return OK or FAIL.
8355  */
8356     static int
8357 get_var_var(name, len, retvar)
8358     char_u	*name;
8359     int		len;		/* length of "name" */
8360     VAR		retvar;		/* NULL when only checking existence */
8361 {
8362     int		ret = OK;
8363     int		type = VAR_UNKNOWN;
8364     long	number = 1;
8365     char_u	*string = NULL;
8366     VAR		v;
8367     int		cc;
8368     int		i;
8369 
8370     /* truncate the name, so that we can use strcmp() */
8371     cc = name[len];
8372     name[len] = NUL;
8373 
8374     /*
8375      * Check for "b:changedtick".
8376      */
8377     if (STRCMP(name, "b:changedtick") == 0)
8378     {
8379 	type = VAR_NUMBER;
8380 	number = curbuf->b_changedtick;
8381     }
8382 
8383     /*
8384      * Check for built-in v: variables.
8385      */
8386     else if ((i = find_vim_var(name, len)) >= 0)
8387     {
8388 	type = vimvars[i].type;
8389 	number = (long)vimvars[i].val;
8390 	string = vimvars[i].val;
8391     }
8392 
8393     /*
8394      * Check for user-defined variables.
8395      */
8396     else
8397     {
8398 	v = find_var(name, FALSE);
8399 	if (v != NULL)
8400 	{
8401 	    type = v->var_type;
8402 	    number = v->var_val.var_number;
8403 	    string = v->var_val.var_string;
8404 	}
8405     }
8406 
8407     if (type == VAR_UNKNOWN)
8408     {
8409 	if (retvar != NULL)
8410 	    EMSG2(_("E121: Undefined variable: %s"), name);
8411 	ret = FAIL;
8412     }
8413     else if (retvar != NULL)
8414     {
8415 	retvar->var_type = type;
8416 	if (type == VAR_NUMBER)
8417 	    retvar->var_val.var_number = number;
8418 	else if (type == VAR_STRING)
8419 	{
8420 	    if (string != NULL)
8421 		string = vim_strsave(string);
8422 	    retvar->var_val.var_string = string;
8423 	}
8424     }
8425 
8426     name[len] = cc;
8427 
8428     return ret;
8429 }
8430 
8431 /*
8432  * Allocate memory for a variable, and make it emtpy (0 or NULL value).
8433  */
8434     static VAR
8435 alloc_var()
8436 {
8437     return (VAR)alloc_clear((unsigned)sizeof(var));
8438 }
8439 
8440 /*
8441  * Allocate memory for a variable, and assign a string to it.
8442  * The string "s" must have been allocated, it is consumed.
8443  * Return NULL for out of memory, the variable otherwise.
8444  */
8445     static VAR
8446 alloc_string_var(s)
8447     char_u	*s;
8448 {
8449     VAR	    retvar;
8450 
8451     retvar = alloc_var();
8452     if (retvar != NULL)
8453     {
8454 	retvar->var_type = VAR_STRING;
8455 	retvar->var_val.var_string = s;
8456     }
8457     else
8458 	vim_free(s);
8459     return retvar;
8460 }
8461 
8462 /*
8463  * Free the memory for a variable.
8464  */
8465     static void
8466 free_var(varp)
8467     VAR	    varp;
8468 {
8469     if (varp != NULL)
8470     {
8471 	if (varp->var_type == VAR_STRING)
8472 	    vim_free(varp->var_val.var_string);
8473 	vim_free(varp->var_name);
8474 	vim_free(varp);
8475     }
8476 }
8477 
8478 /*
8479  * Free the memory for a variable value and set the value to NULL or 0.
8480  */
8481     static void
8482 clear_var(varp)
8483     VAR	    varp;
8484 {
8485     if (varp != NULL)
8486     {
8487 	if (varp->var_type == VAR_STRING)
8488 	{
8489 	    vim_free(varp->var_val.var_string);
8490 	    varp->var_val.var_string = NULL;
8491 	}
8492 	else
8493 	    varp->var_val.var_number = 0;
8494     }
8495 }
8496 
8497 /*
8498  * Get the number value of a variable.
8499  * If it is a String variable, uses vim_str2nr().
8500  */
8501     static long
8502 get_var_number(varp)
8503     VAR		varp;
8504 {
8505     long	n;
8506 
8507     if (varp->var_type == VAR_NUMBER)
8508 	return (long)(varp->var_val.var_number);
8509     else if (varp->var_type == VAR_UNKNOWN || varp->var_val.var_string == NULL)
8510 	return 0L;
8511     else
8512     {
8513 	vim_str2nr(varp->var_val.var_string, NULL, NULL, TRUE, TRUE, &n, NULL);
8514 	return n;
8515     }
8516 }
8517 
8518 /*
8519  * Get the lnum from the first argument.  Also accepts ".", "$", etc.
8520  */
8521     static linenr_T
8522 get_var_lnum(argvars)
8523     VAR		argvars;
8524 {
8525     var		retvar;
8526     linenr_T	lnum;
8527 
8528     lnum = get_var_number(&argvars[0]);
8529     if (lnum == 0)  /* no valid number, try using line() */
8530     {
8531 	retvar.var_type = VAR_NUMBER;
8532 	f_line(argvars, &retvar);
8533 	lnum = retvar.var_val.var_number;
8534 	clear_var(&retvar);
8535     }
8536     return lnum;
8537 }
8538 
8539 /*
8540  * Get the string value of a variable.
8541  * If it is a Number variable, the number is converted into a string.
8542  * get_var_string() uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
8543  * get_var_string_buf() uses a given buffer.
8544  * If the String variable has never been set, return an empty string.
8545  * Never returns NULL;
8546  */
8547     static char_u *
8548 get_var_string(varp)
8549     VAR	    varp;
8550 {
8551     static char_u   mybuf[NUMBUFLEN];
8552 
8553     return get_var_string_buf(varp, mybuf);
8554 }
8555 
8556     static char_u *
8557 get_var_string_buf(varp, buf)
8558     VAR	    varp;
8559     char_u  *buf;
8560 {
8561     if (varp->var_type == VAR_NUMBER)
8562     {
8563 	sprintf((char *)buf, "%ld", (long)varp->var_val.var_number);
8564 	return buf;
8565     }
8566     else if (varp->var_val.var_string == NULL)
8567 	return (char_u *)"";
8568     else
8569 	return varp->var_val.var_string;
8570 }
8571 
8572 /*
8573  * Find variable "name" in the list of variables.
8574  * Return a pointer to it if found, NULL if not found.
8575  */
8576     static VAR
8577 find_var(name, writing)
8578     char_u	*name;
8579     int		writing;
8580 {
8581     int		i;
8582     char_u	*varname;
8583     garray_T	*gap;
8584 
8585     /* Check for function arguments "a:" */
8586     if (name[0] == 'a' && name[1] == ':')
8587     {
8588 	if (writing)
8589 	{
8590 	    EMSG2(_(e_readonlyvar), name);
8591 	    return NULL;
8592 	}
8593 	name += 2;
8594 	if (current_funccal == NULL)
8595 	    return NULL;
8596 	if (VIM_ISDIGIT(*name))
8597 	{
8598 	    i = atol((char *)name);
8599 	    if (i == 0)					/* a:0 */
8600 		return &current_funccal->a0_var;
8601 	    i += current_funccal->func->args.ga_len;
8602 	    if (i > current_funccal->argcount)		/* a:999 */
8603 		return NULL;
8604 	    return &(current_funccal->argvars[i - 1]);	/* a:1, a:2, etc. */
8605 	}
8606 	if (STRCMP(name, "firstline") == 0)
8607 	    return &(current_funccal->firstline);
8608 	if (STRCMP(name, "lastline") == 0)
8609 	    return &(current_funccal->lastline);
8610 	for (i = 0; i < current_funccal->func->args.ga_len; ++i)
8611 	    if (STRCMP(name, ((char_u **)
8612 			      (current_funccal->func->args.ga_data))[i]) == 0)
8613 	    return &(current_funccal->argvars[i]);	/* a:name */
8614 	return NULL;
8615     }
8616 
8617     gap = find_var_ga(name, &varname);
8618     if (gap == NULL)
8619 	return NULL;
8620     return find_var_in_ga(gap, varname);
8621 }
8622 
8623     static VAR
8624 find_var_in_ga(gap, varname)
8625     garray_T	*gap;
8626     char_u	*varname;
8627 {
8628     int	i;
8629 
8630     for (i = gap->ga_len; --i >= 0; )
8631 	if (VAR_GAP_ENTRY(i, gap).var_name != NULL
8632 		&& STRCMP(VAR_GAP_ENTRY(i, gap).var_name, varname) == 0)
8633 	    break;
8634     if (i < 0)
8635 	return NULL;
8636     return &VAR_GAP_ENTRY(i, gap);
8637 }
8638 
8639 /*
8640  * Find the growarray and start of name without ':' for a variable name.
8641  */
8642     static garray_T *
8643 find_var_ga(name, varname)
8644     char_u  *name;
8645     char_u  **varname;
8646 {
8647     if (name[1] != ':')
8648     {
8649 	/* If not "x:name" there must not be any ":" in the name. */
8650 	if (vim_strchr(name, ':') != NULL)
8651 	    return NULL;
8652 	*varname = name;
8653 	if (current_funccal == NULL)
8654 	    return &variables;			/* global variable */
8655 	return &current_funccal->l_vars;	/* local function variable */
8656     }
8657     *varname = name + 2;
8658     if (*name == 'b')				/* buffer variable */
8659 	return &curbuf->b_vars;
8660     if (*name == 'w')				/* window variable */
8661 	return &curwin->w_vars;
8662     if (*name == 'g')				/* global variable */
8663 	return &variables;
8664     if (*name == 'l' && current_funccal != NULL)/* local function variable */
8665 	return &current_funccal->l_vars;
8666     if (*name == 's'				/* script variable */
8667 	    && current_SID > 0 && current_SID <= ga_scripts.ga_len)
8668 	return &SCRIPT_VARS(current_SID);
8669     return NULL;
8670 }
8671 
8672 /*
8673  * Get the string value of a (global/local) variable.
8674  * Returns NULL when it doesn't exist.
8675  */
8676     char_u *
8677 get_var_value(name)
8678     char_u	*name;
8679 {
8680     VAR		v;
8681 
8682     v = find_var(name, FALSE);
8683     if (v == NULL)
8684 	return NULL;
8685     return get_var_string(v);
8686 }
8687 
8688 /*
8689  * Allocate a new growarry for a sourced script.  It will be used while
8690  * sourcing this script and when executing functions defined in the script.
8691  */
8692     void
8693 new_script_vars(id)
8694     scid_T id;
8695 {
8696     if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
8697     {
8698 	while (ga_scripts.ga_len < id)
8699 	{
8700 	    var_init(&SCRIPT_VARS(ga_scripts.ga_len + 1));
8701 	    ++ga_scripts.ga_len;
8702 	    --ga_scripts.ga_room;
8703 	}
8704     }
8705 }
8706 
8707 /*
8708  * Initialize internal variables for use.
8709  */
8710     void
8711 var_init(gap)
8712     garray_T *gap;
8713 {
8714     ga_init2(gap, (int)sizeof(var), 4);
8715 }
8716 
8717 /*
8718  * Clean up a list of internal variables.
8719  */
8720     void
8721 var_clear(gap)
8722     garray_T *gap;
8723 {
8724     int	    i;
8725 
8726     for (i = gap->ga_len; --i >= 0; )
8727 	var_free_one(&VAR_GAP_ENTRY(i, gap));
8728     ga_clear(gap);
8729 }
8730 
8731     static void
8732 var_free_one(v)
8733     VAR	    v;
8734 {
8735     vim_free(v->var_name);
8736     v->var_name = NULL;
8737     if (v->var_type == VAR_STRING)
8738 	vim_free(v->var_val.var_string);
8739     v->var_val.var_string = NULL;
8740 }
8741 
8742 /*
8743  * List the value of one internal variable.
8744  */
8745     static void
8746 list_one_var(v, prefix)
8747     VAR		v;
8748     char_u	*prefix;
8749 {
8750     list_one_var_a(prefix, v->var_name, v->var_type, get_var_string(v));
8751 }
8752 
8753 /*
8754  * List the value of one "v:" variable.
8755  */
8756     static void
8757 list_vim_var(i)
8758     int		i;	/* index in vimvars[] */
8759 {
8760     char_u	*p;
8761     char_u	numbuf[NUMBUFLEN];
8762 
8763     if (vimvars[i].type == VAR_NUMBER)
8764     {
8765 	p = numbuf;
8766 	sprintf((char *)p, "%ld", (long)vimvars[i].val);
8767     }
8768     else if (vimvars[i].val == NULL)
8769 	p = (char_u *)"";
8770     else
8771 	p = vimvars[i].val;
8772     list_one_var_a((char_u *)"v:", (char_u *)vimvars[i].name,
8773 							  vimvars[i].type, p);
8774 }
8775 
8776     static void
8777 list_one_var_a(prefix, name, type, string)
8778     char_u	*prefix;
8779     char_u	*name;
8780     int		type;
8781     char_u	*string;
8782 {
8783     msg_attr(prefix, 0);    /* don't use msg(), it overwrites "v:statusmsg" */
8784     if (name != NULL)	/* "a:" vars don't have a name stored */
8785 	msg_puts(name);
8786     msg_putchar(' ');
8787     msg_advance(22);
8788     if (type == VAR_NUMBER)
8789 	msg_putchar('#');
8790     else
8791 	msg_putchar(' ');
8792     msg_outtrans(string);
8793 }
8794 
8795 /*
8796  * Set variable "name" to value in "varp".
8797  * If the variable already exists, the value is updated.
8798  * Otherwise the variable is created.
8799  */
8800     static void
8801 set_var(name, varp)
8802     char_u	*name;
8803     VAR		varp;
8804 {
8805     int		i;
8806     VAR		v;
8807     char_u	*varname;
8808     garray_T	*gap;
8809 
8810     /*
8811      * Handle setting internal v: variables.
8812      */
8813     i = find_vim_var(name, (int)STRLEN(name));
8814     if (i >= 0)
8815     {
8816 	if (vimvars[i].flags & VV_RO)
8817 	    EMSG2(_(e_readonlyvar), name);
8818 	else
8819 	{
8820 	    if (vimvars[i].type == VAR_STRING)
8821 	    {
8822 		vim_free(vimvars[i].val);
8823 		vimvars[i].val = vim_strsave(get_var_string(varp));
8824 	    }
8825 	    else
8826 		vimvars[i].val = (char_u *)(long)varp->var_val.var_number;
8827 	}
8828 	return;
8829     }
8830 
8831     v = find_var(name, TRUE);
8832     if (v != NULL)	    /* existing variable, only need to free string */
8833     {
8834 	if (v->var_type == VAR_STRING)
8835 	    vim_free(v->var_val.var_string);
8836     }
8837     else		    /* add a new variable */
8838     {
8839 	gap = find_var_ga(name, &varname);
8840 	if (gap == NULL)    /* illegal name */
8841 	{
8842 	    EMSG2(_("E461: Illegal variable name: %s"), name);
8843 	    return;
8844 	}
8845 
8846 	/* Try to use an empty entry */
8847 	for (i = gap->ga_len; --i >= 0; )
8848 	    if (VAR_GAP_ENTRY(i, gap).var_name == NULL)
8849 		break;
8850 	if (i < 0)	    /* need to allocate more room */
8851 	{
8852 	    if (ga_grow(gap, 1) == FAIL)
8853 		return;
8854 	    i = gap->ga_len;
8855 	}
8856 	v = &VAR_GAP_ENTRY(i, gap);
8857 	if ((v->var_name = vim_strsave(varname)) == NULL)
8858 	    return;
8859 	if (i == gap->ga_len)
8860 	{
8861 	    ++gap->ga_len;
8862 	    --gap->ga_room;
8863 	}
8864     }
8865     copy_var(varp, v);
8866 }
8867 
8868     static void
8869 copy_var(from, to)
8870     VAR	from;
8871     VAR	to;
8872 {
8873     to->var_type = from->var_type;
8874     if (from->var_type == VAR_STRING)
8875 	to->var_val.var_string = vim_strsave(get_var_string(from));
8876     else
8877 	to->var_val.var_number = from->var_val.var_number;
8878 }
8879 
8880 /*
8881  * ":echo expr1 ..."	print each argument separated with a space, add a
8882  *			newline at the end.
8883  * ":echon expr1 ..."	print each argument plain.
8884  */
8885     void
8886 ex_echo(eap)
8887     exarg_T	*eap;
8888 {
8889     char_u	*arg = eap->arg;
8890     var		retvar;
8891     char_u	*p;
8892     int		needclr = TRUE;
8893     int		atstart = TRUE;
8894 
8895     if (eap->skip)
8896 	++emsg_skip;
8897     while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
8898     {
8899 	p = arg;
8900 	if (eval1(&arg, &retvar, !eap->skip) == FAIL)
8901 	{
8902 	    /*
8903 	     * Report the invalid expression unless the expression evaluation
8904 	     * has been cancelled due to an aborting error, an interrupt, or an
8905 	     * exception.
8906 	     */
8907 	    if (!aborting())
8908 		EMSG2(_(e_invexpr2), p);
8909 	    break;
8910 	}
8911 	if (!eap->skip)
8912 	{
8913 	    if (atstart)
8914 	    {
8915 		atstart = FALSE;
8916 		/* Call msg_start() after eval1(), evaluating the expression
8917 		 * may cause a message to appear. */
8918 		if (eap->cmdidx == CMD_echo)
8919 		    msg_start();
8920 	    }
8921 	    else if (eap->cmdidx == CMD_echo)
8922 		msg_puts_attr((char_u *)" ", echo_attr);
8923 	    for (p = get_var_string(&retvar); *p != NUL && !got_int; ++p)
8924 		if (*p == '\n' || *p == '\r' || *p == TAB)
8925 		{
8926 		    if (*p != TAB && needclr)
8927 		    {
8928 			/* remove any text still there from the command */
8929 			msg_clr_eos();
8930 			needclr = FALSE;
8931 		    }
8932 		    msg_putchar_attr(*p, echo_attr);
8933 		}
8934 		else
8935 		{
8936 #ifdef FEAT_MBYTE
8937 		    if (has_mbyte)
8938 		    {
8939 			int i = (*mb_ptr2len_check)(p);
8940 
8941 			(void)msg_outtrans_len_attr(p, i, echo_attr);
8942 			p += i - 1;
8943 		    }
8944 		    else
8945 #endif
8946 			(void)msg_outtrans_len_attr(p, 1, echo_attr);
8947 		}
8948 	}
8949 	clear_var(&retvar);
8950 	arg = skipwhite(arg);
8951     }
8952     eap->nextcmd = check_nextcmd(arg);
8953 
8954     if (eap->skip)
8955 	--emsg_skip;
8956     else
8957     {
8958 	/* remove text that may still be there from the command */
8959 	if (needclr)
8960 	    msg_clr_eos();
8961 	if (eap->cmdidx == CMD_echo)
8962 	    msg_end();
8963     }
8964 }
8965 
8966 /*
8967  * ":echohl {name}".
8968  */
8969     void
8970 ex_echohl(eap)
8971     exarg_T	*eap;
8972 {
8973     int		id;
8974 
8975     id = syn_name2id(eap->arg);
8976     if (id == 0)
8977 	echo_attr = 0;
8978     else
8979 	echo_attr = syn_id2attr(id);
8980 }
8981 
8982 /*
8983  * ":execute expr1 ..."	execute the result of an expression.
8984  * ":echomsg expr1 ..."	Print a message
8985  * ":echoerr expr1 ..."	Print an error
8986  * Each gets spaces around each argument and a newline at the end for
8987  * echo commands
8988  */
8989     void
8990 ex_execute(eap)
8991     exarg_T	*eap;
8992 {
8993     char_u	*arg = eap->arg;
8994     var		retvar;
8995     int		ret = OK;
8996     char_u	*p;
8997     garray_T	ga;
8998     int		len;
8999     int		save_did_emsg;
9000 
9001     ga_init2(&ga, 1, 80);
9002 
9003     if (eap->skip)
9004 	++emsg_skip;
9005     while (*arg != NUL && *arg != '|' && *arg != '\n')
9006     {
9007 	p = arg;
9008 	if (eval1(&arg, &retvar, !eap->skip) == FAIL)
9009 	{
9010 	    /*
9011 	     * Report the invalid expression unless the expression evaluation
9012 	     * has been cancelled due to an aborting error, an interrupt, or an
9013 	     * exception.
9014 	     */
9015 	    if (!aborting())
9016 		EMSG2(_(e_invexpr2), p);
9017 	    ret = FAIL;
9018 	    break;
9019 	}
9020 
9021 	if (!eap->skip)
9022 	{
9023 	    p = get_var_string(&retvar);
9024 	    len = (int)STRLEN(p);
9025 	    if (ga_grow(&ga, len + 2) == FAIL)
9026 	    {
9027 		clear_var(&retvar);
9028 		ret = FAIL;
9029 		break;
9030 	    }
9031 	    if (ga.ga_len)
9032 	    {
9033 		((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
9034 		--ga.ga_room;
9035 	    }
9036 	    STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
9037 	    ga.ga_room -= len;
9038 	    ga.ga_len += len;
9039 	}
9040 
9041 	clear_var(&retvar);
9042 	arg = skipwhite(arg);
9043     }
9044 
9045     if (ret != FAIL && ga.ga_data != NULL)
9046     {
9047 	if (eap->cmdidx == CMD_echomsg)
9048 	    MSG_ATTR(ga.ga_data, echo_attr);
9049 	else if (eap->cmdidx == CMD_echoerr)
9050 	{
9051 	    /* We don't want to abort following commands, restore did_emsg. */
9052 	    save_did_emsg = did_emsg;
9053 	    EMSG((char_u *)ga.ga_data);
9054 	    if (!force_abort)
9055 		did_emsg = save_did_emsg;
9056 	}
9057 	else if (eap->cmdidx == CMD_execute)
9058 	    do_cmdline((char_u *)ga.ga_data,
9059 		       eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
9060     }
9061 
9062     ga_clear(&ga);
9063 
9064     if (eap->skip)
9065 	--emsg_skip;
9066 
9067     eap->nextcmd = check_nextcmd(arg);
9068 }
9069 
9070 /*
9071  * Skip over the name of an option: "&option", "&g:option" or "&l:option".
9072  * "arg" points to the "&" or '+' when called, to "option" when returning.
9073  * Returns NULL when no option name found.  Otherwise pointer to the char
9074  * after the option name.
9075  */
9076     static char_u *
9077 find_option_end(arg, opt_flags)
9078     char_u	**arg;
9079     int		*opt_flags;
9080 {
9081     char_u	*p = *arg;
9082 
9083     ++p;
9084     if (*p == 'g' && p[1] == ':')
9085     {
9086 	*opt_flags = OPT_GLOBAL;
9087 	p += 2;
9088     }
9089     else if (*p == 'l' && p[1] == ':')
9090     {
9091 	*opt_flags = OPT_LOCAL;
9092 	p += 2;
9093     }
9094     else
9095 	*opt_flags = 0;
9096 
9097     if (!ASCII_ISALPHA(*p))
9098 	return NULL;
9099     *arg = p;
9100 
9101     if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
9102 	p += 4;	    /* termcap option */
9103     else
9104 	while (ASCII_ISALPHA(*p))
9105 	    ++p;
9106     return p;
9107 }
9108 
9109 /*
9110  * ":function"
9111  */
9112     void
9113 ex_function(eap)
9114     exarg_T	*eap;
9115 {
9116     char_u	*theline;
9117     int		j;
9118     int		c;
9119 #ifdef FEAT_MAGIC_BRACES
9120     int		saved_did_emsg;
9121 #endif
9122     char_u	*name = NULL;
9123     char_u	*p;
9124     char_u	*arg;
9125     garray_T	newargs;
9126     garray_T	newlines;
9127     int		varargs = FALSE;
9128     int		mustend = FALSE;
9129     int		flags = 0;
9130     ufunc_T	*fp;
9131     int		indent;
9132     int		nesting;
9133     char_u	*skip_until = NULL;
9134     static char_u e_funcexts[] = N_("E122: Function %s already exists, add ! to replace it");
9135 
9136     /*
9137      * ":function" without argument: list functions.
9138      */
9139     if (ends_excmd(*eap->arg))
9140     {
9141 	if (!eap->skip)
9142 	    for (fp = firstfunc; fp != NULL && !got_int; fp = fp->next)
9143 		list_func_head(fp, FALSE);
9144 	eap->nextcmd = check_nextcmd(eap->arg);
9145 	return;
9146     }
9147 
9148     p = eap->arg;
9149     name = trans_function_name(&p, eap->skip, FALSE);
9150     if (name == NULL && !eap->skip)
9151     {
9152 	/*
9153 	 * Return on an invalid expression in braces, unless the expression
9154 	 * evaluation has been cancelled due to an aborting error, an
9155 	 * interrupt, or an exception.
9156 	 */
9157 	if (!aborting())
9158 	    return;
9159 	else
9160 	    eap->skip = TRUE;
9161     }
9162 #ifdef FEAT_MAGIC_BRACES
9163     /* An error in a function call during evaluation of an expression in magic
9164      * braces should not cause the function not to be defined. */
9165     saved_did_emsg = did_emsg;
9166     did_emsg = FALSE;
9167 #endif
9168 
9169     /*
9170      * ":function func" with only function name: list function.
9171      */
9172     if (vim_strchr(p, '(') == NULL)
9173     {
9174 	if (!ends_excmd(*skipwhite(p)))
9175 	{
9176 	    EMSG(_(e_trailing));
9177 	    goto erret_name;
9178 	}
9179 	eap->nextcmd = check_nextcmd(p);
9180 	if (eap->nextcmd != NULL)
9181 	    *p = NUL;
9182 	if (!eap->skip && !got_int)
9183 	{
9184 	    fp = find_func(name);
9185 	    if (fp != NULL)
9186 	    {
9187 		list_func_head(fp, TRUE);
9188 		for (j = 0; j < fp->lines.ga_len && !got_int; ++j)
9189 		{
9190 		    msg_putchar('\n');
9191 		    msg_outnum((long)(j + 1));
9192 		    if (j < 9)
9193 			msg_putchar(' ');
9194 		    if (j < 99)
9195 			msg_putchar(' ');
9196 		    msg_prt_line(FUNCLINE(fp, j));
9197 		    out_flush();	/* show a line at a time */
9198 		    ui_breakcheck();
9199 		}
9200 		if (!got_int)
9201 		{
9202 		    msg_putchar('\n');
9203 		    msg_puts((char_u *)"   endfunction");
9204 		}
9205 	    }
9206 	    else
9207 		EMSG2(_("E123: Undefined function: %s"), eap->arg);
9208 	}
9209 	goto erret_name;
9210     }
9211 
9212     /*
9213      * ":function name(arg1, arg2)" Define function.
9214      */
9215     p = skipwhite(p);
9216     if (*p != '(')
9217     {
9218 	if (!eap->skip)
9219 	{
9220 	    EMSG2(_("E124: Missing '(': %s"), eap->arg);
9221 	    goto erret_name;
9222 	}
9223 	/* attempt to continue by skipping some text */
9224 	if (vim_strchr(p, '(') != NULL)
9225 	    p = vim_strchr(p, '(');
9226     }
9227     p = skipwhite(p + 1);
9228 
9229     ga_init2(&newargs, (int)sizeof(char_u *), 3);
9230     ga_init2(&newlines, (int)sizeof(char_u *), 3);
9231 
9232     /*
9233      * Isolate the arguments: "arg1, arg2, ...)"
9234      */
9235     while (*p != ')')
9236     {
9237 	if (p[0] == '.' && p[1] == '.' && p[2] == '.')
9238 	{
9239 	    varargs = TRUE;
9240 	    p += 3;
9241 	    mustend = TRUE;
9242 	}
9243 	else
9244 	{
9245 	    arg = p;
9246 	    while (ASCII_ISALNUM(*p) || *p == '_')
9247 		++p;
9248 	    if (arg == p || isdigit(*arg)
9249 		    || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
9250 		    || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0))
9251 	    {
9252 		if (!eap->skip)
9253 		    EMSG2(_("E125: Illegal argument: %s"), arg);
9254 		break;
9255 	    }
9256 	    if (ga_grow(&newargs, 1) == FAIL)
9257 		goto erret;
9258 	    c = *p;
9259 	    *p = NUL;
9260 	    arg = vim_strsave(arg);
9261 	    if (arg == NULL)
9262 		goto erret;
9263 	    ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
9264 	    *p = c;
9265 	    newargs.ga_len++;
9266 	    newargs.ga_room--;
9267 	    if (*p == ',')
9268 		++p;
9269 	    else
9270 		mustend = TRUE;
9271 	}
9272 	p = skipwhite(p);
9273 	if (mustend && *p != ')')
9274 	{
9275 	    if (!eap->skip)
9276 		EMSG2(_(e_invarg2), eap->arg);
9277 	    break;
9278 	}
9279     }
9280     ++p;	/* skip the ')' */
9281 
9282     /* find extra arguments "range" and "abort" */
9283     for (;;)
9284     {
9285 	p = skipwhite(p);
9286 	if (STRNCMP(p, "range", 5) == 0)
9287 	{
9288 	    flags |= FC_RANGE;
9289 	    p += 5;
9290 	}
9291 	else if (STRNCMP(p, "abort", 5) == 0)
9292 	{
9293 	    flags |= FC_ABORT;
9294 	    p += 5;
9295 	}
9296 	else
9297 	    break;
9298     }
9299 
9300     if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg)
9301 	EMSG(_(e_trailing));
9302 
9303     /*
9304      * Read the body of the function, until ":endfunction" is found.
9305      */
9306     if (KeyTyped)
9307     {
9308 	/* Check if the function already exists, don't let the user type the
9309 	 * whole function before telling him it doesn't work!  For a script we
9310 	 * need to skip the body to be able to find what follows. */
9311 	if (!eap->skip && !eap->forceit && find_func(name) != NULL)
9312 	    EMSG2(_(e_funcexts), name);
9313 
9314 	msg_putchar('\n');	    /* don't overwrite the function name */
9315 	cmdline_row = msg_row;
9316     }
9317 
9318     indent = 2;
9319     nesting = 0;
9320     for (;;)
9321     {
9322 	msg_scroll = TRUE;
9323 	need_wait_return = FALSE;
9324 	if (eap->getline == NULL)
9325 	    theline = getcmdline(':', 0L, indent);
9326 	else
9327 	    theline = eap->getline(':', eap->cookie, indent);
9328 	if (KeyTyped)
9329 	    lines_left = Rows - 1;
9330 	if (theline == NULL)
9331 	{
9332 	    EMSG(_("E126: Missing :endfunction"));
9333 	    goto erret;
9334 	}
9335 
9336 	if (skip_until != NULL)
9337 	{
9338 	    /* between ":append" and "." and between ":python <<EOF" and "EOF"
9339 	     * don't check for ":endfunc". */
9340 	    if (STRCMP(theline, skip_until) == 0)
9341 	    {
9342 		vim_free(skip_until);
9343 		skip_until = NULL;
9344 	    }
9345 	}
9346 	else
9347 	{
9348 	    /* skip ':' and blanks*/
9349 	    for (p = theline; vim_iswhite(*p) || *p == ':'; ++p)
9350 		;
9351 
9352 	    /* Check for "endfunction" (should be more strict...). */
9353 	    if (STRNCMP(p, "endf", 4) == 0 && nesting-- == 0)
9354 	    {
9355 		vim_free(theline);
9356 		break;
9357 	    }
9358 
9359 	    /* Increase indent inside "if", "while", and "try", decrease
9360 	     * at "end". */
9361 	    if (indent > 2 && STRNCMP(p, "end", 3) == 0)
9362 		indent -= 2;
9363 	    else if (STRNCMP(p, "if", 2) == 0 || STRNCMP(p, "wh", 2) == 0
9364 		    || STRNCMP(p, "try", 3) == 0)
9365 		indent += 2;
9366 
9367 	    /* Check for defining a function inside this function. */
9368 	    if (STRNCMP(p, "fu", 2) == 0)
9369 	    {
9370 		p = skipwhite(skiptowhite(p));
9371 		p += eval_fname_script(p);
9372 		if (ASCII_ISALPHA(*p))
9373 		{
9374 		    vim_free(trans_function_name(&p, TRUE, FALSE));
9375 		    if (*skipwhite(p) == '(')
9376 		    {
9377 			++nesting;
9378 			indent += 2;
9379 		    }
9380 		}
9381 	    }
9382 
9383 	    /* Check for ":append" or ":insert". */
9384 	    p = skip_range(p, NULL);
9385 	    if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
9386 		    || (p[0] == 'i'
9387 			&& (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
9388 				&& (!ASCII_ISALPHA(p[2]) || (p[2] == 's'))))))
9389 		skip_until = vim_strsave((char_u *)".");
9390 
9391 	    /* Check for ":python <<EOF", ":tcl <<EOF", etc. */
9392 	    arg = skipwhite(skiptowhite(p));
9393 	    if (arg[0] == '<' && arg[1] =='<'
9394 		    && ((p[0] == 'p' && p[1] == 'y'
9395 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 't'))
9396 			|| (p[0] == 'p' && p[1] == 'e'
9397 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
9398 			|| (p[0] == 't' && p[1] == 'c'
9399 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'l'))
9400 			|| (p[0] == 'r' && p[1] == 'u' && p[2] == 'b'
9401 				    && (!ASCII_ISALPHA(p[3]) || p[3] == 'y'))
9402 			|| (p[0] == 'm' && p[1] == 'z'
9403 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 's'))
9404 			))
9405 	    {
9406 		/* ":python <<" continues until a dot, like ":append" */
9407 		p = skipwhite(arg + 2);
9408 		if (*p == NUL)
9409 		    skip_until = vim_strsave((char_u *)".");
9410 		else
9411 		    skip_until = vim_strsave(p);
9412 	    }
9413 	}
9414 
9415 	/* Add the line to the function. */
9416 	if (ga_grow(&newlines, 1) == FAIL)
9417 	    goto erret;
9418 	((char_u **)(newlines.ga_data))[newlines.ga_len] = theline;
9419 	newlines.ga_len++;
9420 	newlines.ga_room--;
9421     }
9422 
9423     /* Don't define the function when skipping commands or when an error was
9424      * detected. */
9425     if (eap->skip || did_emsg)
9426 	goto erret;
9427 
9428     /*
9429      * If there are no errors, add the function
9430      */
9431     fp = find_func(name);
9432     if (fp != NULL)
9433     {
9434 	if (!eap->forceit)
9435 	{
9436 	    EMSG2(_(e_funcexts), name);
9437 	    goto erret;
9438 	}
9439 	if (fp->calls)
9440 	{
9441 	    EMSG2(_("E127: Cannot redefine function %s: It is in use"), name);
9442 	    goto erret;
9443 	}
9444 	/* redefine existing function */
9445 	ga_clear_strings(&(fp->args));
9446 	ga_clear_strings(&(fp->lines));
9447 	vim_free(name);
9448     }
9449     else
9450     {
9451 	fp = (ufunc_T *)alloc((unsigned)sizeof(ufunc_T));
9452 	if (fp == NULL)
9453 	    goto erret;
9454 	/* insert the new function in the function list */
9455 	fp->next = firstfunc;
9456 	firstfunc = fp;
9457 	fp->name = name;
9458     }
9459     fp->args = newargs;
9460     fp->lines = newlines;
9461     fp->varargs = varargs;
9462     fp->flags = flags;
9463     fp->calls = 0;
9464     fp->script_ID = current_SID;
9465 #ifdef FEAT_MAGIC_BRACES
9466     did_emsg |= saved_did_emsg;
9467 #endif
9468     vim_free(skip_until);
9469     return;
9470 
9471 erret:
9472     vim_free(skip_until);
9473     ga_clear_strings(&newargs);
9474     ga_clear_strings(&newlines);
9475 erret_name:
9476     vim_free(name);
9477 #ifdef FEAT_MAGIC_BRACES
9478     did_emsg |= saved_did_emsg;
9479 #endif
9480 }
9481 
9482 /*
9483  * Get a function name, translating "<SID>" and "<SNR>".
9484  * Returns the function name in allocated memory, or NULL for failure.
9485  * Advances "pp" to just after the function name (if no error).
9486  */
9487     static char_u *
9488 trans_function_name(pp, skip, internal)
9489     char_u	**pp;
9490     int		skip;		/* only find the end, don't evaluate */
9491     int		internal;	/* TRUE if internal function name OK */
9492 {
9493     char_u	*name;
9494     char_u	*start;
9495     char_u	*end;
9496     int		lead;
9497     char_u	sid_buf[20];
9498     char_u	*temp_string = NULL;
9499     char_u	*expr_start, *expr_end;
9500     int		len;
9501 
9502     /* A name starting with "<SID>" or "<SNR>" is local to a script. */
9503     start = *pp;
9504     lead = eval_fname_script(start);
9505     if (lead > 0)
9506 	start += lead;
9507     end = find_name_end(start, &expr_start, &expr_end);
9508     if (end == start)
9509     {
9510 	if (!skip)
9511 	    EMSG(_("E129: Function name required"));
9512 	return NULL;
9513     }
9514 #ifdef FEAT_MAGIC_BRACES
9515     if (expr_start != NULL && !skip)
9516     {
9517 	/* expand magic curlies */
9518 	temp_string = make_expanded_name(start, expr_start, expr_end, end);
9519 	if (temp_string == NULL)
9520 	{
9521 	    /*
9522 	     * Report an invalid expression in braces, unless the expression
9523 	     * evaluation has been cancelled due to an aborting error, an
9524 	     * interrupt, or an exception.
9525 	     */
9526 	    if (!aborting())
9527 		EMSG2(_(e_invarg2), start);
9528 	    else
9529 		*pp = end;
9530 	    return NULL;
9531 	}
9532 	start = temp_string;
9533 	len = (int)STRLEN(temp_string);
9534     }
9535     else
9536 #endif
9537 	len = (int)(end - start);
9538 
9539     /*
9540      * Copy the function name to allocated memory.
9541      * Accept <SID>name() inside a script, translate into <SNR>123_name().
9542      * Accept <SNR>123_name() outside a script.
9543      */
9544     if (skip)
9545 	lead = 0;	/* do nothing */
9546     else if (lead > 0)
9547     {
9548 	lead = 3;
9549 	if (eval_fname_sid(*pp))	/* If it's "<SID>" */
9550 	{
9551 	    if (current_SID <= 0)
9552 	    {
9553 		EMSG(_(e_usingsid));
9554 		return NULL;
9555 	    }
9556 	    sprintf((char *)sid_buf, "%ld_", (long)current_SID);
9557 	    lead += (int)STRLEN(sid_buf);
9558 	}
9559     }
9560     else if (!internal && !ASCII_ISUPPER(*start))
9561     {
9562 	EMSG2(_("E128: Function name must start with a capital: %s"), start);
9563 	return NULL;
9564     }
9565     name = alloc((unsigned)(len + lead + 1));
9566     if (name != NULL)
9567     {
9568 	if (lead > 0)
9569 	{
9570 	    name[0] = K_SPECIAL;
9571 	    name[1] = KS_EXTRA;
9572 	    name[2] = (int)KE_SNR;
9573 	    if (eval_fname_sid(*pp))	/* If it's "<SID>" */
9574 		STRCPY(name + 3, sid_buf);
9575 	}
9576 	mch_memmove(name + lead, start, (size_t)len);
9577 	name[len + lead] = NUL;
9578     }
9579     *pp = end;
9580 
9581     vim_free(temp_string);
9582     return name;
9583 }
9584 
9585 /*
9586  * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
9587  * Return 2 if "p" starts with "s:".
9588  * Return 0 otherwise.
9589  */
9590     static int
9591 eval_fname_script(p)
9592     char_u	*p;
9593 {
9594     if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0
9595 					  || STRNICMP(p + 1, "SNR>", 4) == 0))
9596 	return 5;
9597     if (p[0] == 's' && p[1] == ':')
9598 	return 2;
9599     return 0;
9600 }
9601 
9602 /*
9603  * Return TRUE if "p" starts with "<SID>" or "s:".
9604  * Only works if eval_fname_script() returned non-zero for "p"!
9605  */
9606     static int
9607 eval_fname_sid(p)
9608     char_u	*p;
9609 {
9610     return (*p == 's' || TOUPPER_ASC(p[2]) == 'I');
9611 }
9612 
9613 /*
9614  * List the head of the function: "name(arg1, arg2)".
9615  */
9616     static void
9617 list_func_head(fp, indent)
9618     ufunc_T	*fp;
9619     int		indent;
9620 {
9621     int		j;
9622 
9623     msg_start();
9624     if (indent)
9625 	MSG_PUTS("   ");
9626     MSG_PUTS("function ");
9627     if (fp->name[0] == K_SPECIAL)
9628     {
9629 	MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
9630 	msg_puts(fp->name + 3);
9631     }
9632     else
9633 	msg_puts(fp->name);
9634     msg_putchar('(');
9635     for (j = 0; j < fp->args.ga_len; ++j)
9636     {
9637 	if (j)
9638 	    MSG_PUTS(", ");
9639 	msg_puts(FUNCARG(fp, j));
9640     }
9641     if (fp->varargs)
9642     {
9643 	if (j)
9644 	    MSG_PUTS(", ");
9645 	MSG_PUTS("...");
9646     }
9647     msg_putchar(')');
9648 }
9649 
9650 /*
9651  * Find a function by name, return pointer to it in ufuncs.
9652  * Return NULL for unknown function.
9653  */
9654     static ufunc_T *
9655 find_func(name)
9656     char_u	*name;
9657 {
9658     ufunc_T	*fp;
9659 
9660     for (fp = firstfunc; fp != NULL; fp = fp->next)
9661 	if (STRCMP(name, fp->name) == 0)
9662 	    break;
9663     return fp;
9664 }
9665 
9666 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
9667 
9668 /*
9669  * Function given to ExpandGeneric() to obtain the list of user defined
9670  * function names.
9671  */
9672     char_u *
9673 get_user_func_name(xp, idx)
9674     expand_T	*xp;
9675     int		idx;
9676 {
9677     static ufunc_T *fp = NULL;
9678 
9679     if (idx == 0)
9680 	fp = firstfunc;
9681     if (fp != NULL)
9682     {
9683 	if (STRLEN(fp->name) + 4 >= IOSIZE)
9684 	    return fp->name;	/* prevents overflow */
9685 
9686 	cat_func_name(IObuff, fp);
9687 	if (xp->xp_context != EXPAND_USER_FUNC)
9688 	{
9689 	    STRCAT(IObuff, "(");
9690 	    if (!fp->varargs && fp->args.ga_len == 0)
9691 		STRCAT(IObuff, ")");
9692 	}
9693 
9694 	fp = fp->next;
9695 	return IObuff;
9696     }
9697     return NULL;
9698 }
9699 
9700 #endif /* FEAT_CMDL_COMPL */
9701 
9702 /*
9703  * Copy the function name of "fp" to buffer "buf".
9704  * "buf" must be able to hold the function name plus three bytes.
9705  * Takes care of script-local function names.
9706  */
9707     static void
9708 cat_func_name(buf, fp)
9709     char_u	*buf;
9710     ufunc_T	*fp;
9711 {
9712     if (fp->name[0] == K_SPECIAL)
9713     {
9714 	STRCPY(buf, "<SNR>");
9715 	STRCAT(buf, fp->name + 3);
9716     }
9717     else
9718 	STRCPY(buf, fp->name);
9719 }
9720 
9721 /*
9722  * ":delfunction {name}"
9723  */
9724     void
9725 ex_delfunction(eap)
9726     exarg_T	*eap;
9727 {
9728     ufunc_T	*fp = NULL, *pfp;
9729     char_u	*p;
9730     char_u	*name;
9731 
9732     p = eap->arg;
9733     name = trans_function_name(&p, eap->skip, FALSE);
9734     if (name == NULL)
9735 	return;
9736     if (!ends_excmd(*skipwhite(p)))
9737     {
9738 	vim_free(name);
9739 	EMSG(_(e_trailing));
9740 	return;
9741     }
9742     eap->nextcmd = check_nextcmd(p);
9743     if (eap->nextcmd != NULL)
9744 	*p = NUL;
9745 
9746     if (!eap->skip)
9747 	fp = find_func(name);
9748     vim_free(name);
9749 
9750     if (!eap->skip)
9751     {
9752 	if (fp == NULL)
9753 	{
9754 	    EMSG2(_("E130: Undefined function: %s"), eap->arg);
9755 	    return;
9756 	}
9757 	if (fp->calls)
9758 	{
9759 	    EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg);
9760 	    return;
9761 	}
9762 
9763 	/* clear this function */
9764 	vim_free(fp->name);
9765 	ga_clear_strings(&(fp->args));
9766 	ga_clear_strings(&(fp->lines));
9767 
9768 	/* remove the function from the function list */
9769 	if (firstfunc == fp)
9770 	    firstfunc = fp->next;
9771 	else
9772 	{
9773 	    for (pfp = firstfunc; pfp != NULL; pfp = pfp->next)
9774 		if (pfp->next == fp)
9775 		{
9776 		    pfp->next = fp->next;
9777 		    break;
9778 		}
9779 	}
9780 	vim_free(fp);
9781     }
9782 }
9783 
9784 /*
9785  * Call a user function.
9786  */
9787     static void
9788 call_user_func(fp, argcount, argvars, retvar, firstline, lastline)
9789     ufunc_T	*fp;		/* pointer to function */
9790     int		argcount;	/* nr of args */
9791     VAR		argvars;	/* arguments */
9792     VAR		retvar;		/* return value */
9793     linenr_T	firstline;	/* first line of range */
9794     linenr_T	lastline;	/* last line of range */
9795 {
9796     char_u		*save_sourcing_name;
9797     linenr_T		save_sourcing_lnum;
9798     scid_T		save_current_SID;
9799     struct funccall	fc;
9800     struct funccall	*save_fcp = current_funccal;
9801     int			save_did_emsg;
9802     static int		depth = 0;
9803 
9804     /* If depth of calling is getting too high, don't execute the function */
9805     if (depth >= p_mfd)
9806     {
9807 	EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'"));
9808 	retvar->var_type = VAR_NUMBER;
9809 	retvar->var_val.var_number = -1;
9810 	return;
9811     }
9812     ++depth;
9813 
9814     line_breakcheck();		/* check for CTRL-C hit */
9815 
9816     /* set local variables */
9817     var_init(&fc.l_vars);
9818     fc.func = fp;
9819     fc.argcount = argcount;
9820     fc.argvars = argvars;
9821     fc.retvar = retvar;
9822     retvar->var_val.var_number = 0;
9823     fc.linenr = 0;
9824     fc.returned = FALSE;
9825     fc.level = ex_nesting_level;
9826     fc.a0_var.var_type = VAR_NUMBER;
9827     fc.a0_var.var_val.var_number = argcount - fp->args.ga_len;
9828     fc.a0_var.var_name = NULL;
9829     current_funccal = &fc;
9830     fc.firstline.var_type = VAR_NUMBER;
9831     fc.firstline.var_val.var_number = firstline;
9832     fc.firstline.var_name = NULL;
9833     fc.lastline.var_type = VAR_NUMBER;
9834     fc.lastline.var_val.var_number = lastline;
9835     fc.lastline.var_name = NULL;
9836     /* Check if this function has a breakpoint. */
9837     fc.breakpoint = dbg_find_breakpoint(FALSE, fp->name, (linenr_T)0);
9838     fc.dbg_tick = debug_tick;
9839 
9840     /* Don't redraw while executing the function. */
9841     ++RedrawingDisabled;
9842     save_sourcing_name = sourcing_name;
9843     save_sourcing_lnum = sourcing_lnum;
9844     sourcing_lnum = 1;
9845     sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0
9846 		: STRLEN(save_sourcing_name)) + STRLEN(fp->name) + 13));
9847     if (sourcing_name != NULL)
9848     {
9849 	if (save_sourcing_name != NULL
9850 			  && STRNCMP(save_sourcing_name, "function ", 9) == 0)
9851 	    sprintf((char *)sourcing_name, "%s..", save_sourcing_name);
9852 	else
9853 	    STRCPY(sourcing_name, "function ");
9854 	cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
9855 
9856 	if (p_verbose >= 12)
9857 	{
9858 	    ++no_wait_return;
9859 	    msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
9860 	    msg_str((char_u *)_("calling %s"), sourcing_name);
9861 	    if (p_verbose >= 14)
9862 	    {
9863 		int	i;
9864 		char_u	buf[MSG_BUF_LEN];
9865 
9866 		msg_puts((char_u *)"(");
9867 		for (i = 0; i < argcount; ++i)
9868 		{
9869 		    if (i > 0)
9870 			msg_puts((char_u *)", ");
9871 		    if (argvars[i].var_type == VAR_NUMBER)
9872 			msg_outnum((long)argvars[i].var_val.var_number);
9873 		    else
9874 		    {
9875 			trunc_string(get_var_string(&argvars[i]),
9876 							    buf, MSG_BUF_LEN);
9877 			msg_puts((char_u *)"\"");
9878 			msg_puts(buf);
9879 			msg_puts((char_u *)"\"");
9880 		    }
9881 		}
9882 		msg_puts((char_u *)")");
9883 	    }
9884 	    msg_puts((char_u *)"\n");   /* don't overwrite this either */
9885 	    cmdline_row = msg_row;
9886 	    --no_wait_return;
9887 	}
9888     }
9889     save_current_SID = current_SID;
9890     current_SID = fp->script_ID;
9891     save_did_emsg = did_emsg;
9892     did_emsg = FALSE;
9893 
9894     /* call do_cmdline() to execute the lines */
9895     do_cmdline(NULL, get_func_line, (void *)&fc,
9896 				     DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
9897 
9898     --RedrawingDisabled;
9899 
9900     /* when the function was aborted because of an error, return -1 */
9901     if ((did_emsg && (fp->flags & FC_ABORT)) || retvar->var_type == VAR_UNKNOWN)
9902     {
9903 	clear_var(retvar);
9904 	retvar->var_type = VAR_NUMBER;
9905 	retvar->var_val.var_number = -1;
9906     }
9907 
9908     /* when being verbose, mention the return value */
9909     if (p_verbose >= 12)
9910     {
9911 	char_u	*sn, *val;
9912 
9913 	++no_wait_return;
9914 	msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
9915 
9916 	/* Make sure the output fits in IObuff. */
9917 	sn = sourcing_name;
9918 	if (STRLEN(sourcing_name) > IOSIZE / 2 - 50)
9919 	    sn = sourcing_name + STRLEN(sourcing_name) - (IOSIZE / 2 - 50);
9920 
9921 	if (aborting())
9922 	    smsg((char_u *)_("%s aborted"), sn);
9923 	else if (fc.retvar->var_type == VAR_NUMBER)
9924 	    smsg((char_u *)_("%s returning #%ld"), sn,
9925 				       (long)fc.retvar->var_val.var_number);
9926 	else if (fc.retvar->var_type == VAR_STRING)
9927 	{
9928 	    val = get_var_string(fc.retvar);
9929 	    if (STRLEN(val) > IOSIZE / 2 - 50)
9930 		val = val + STRLEN(val) - (IOSIZE / 2 - 50);
9931 	    smsg((char_u *)_("%s returning \"%s\""), sn, val);
9932 	}
9933 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
9934 	cmdline_row = msg_row;
9935 	--no_wait_return;
9936     }
9937 
9938     vim_free(sourcing_name);
9939     sourcing_name = save_sourcing_name;
9940     sourcing_lnum = save_sourcing_lnum;
9941     current_SID = save_current_SID;
9942 
9943     if (p_verbose >= 12 && sourcing_name != NULL)
9944     {
9945 	++no_wait_return;
9946 	msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
9947 	msg_str((char_u *)_("continuing in %s"), sourcing_name);
9948 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
9949 	cmdline_row = msg_row;
9950 	--no_wait_return;
9951     }
9952 
9953     did_emsg |= save_did_emsg;
9954     current_funccal = save_fcp;
9955 
9956     var_clear(&fc.l_vars);		/* free all local variables */
9957     --depth;
9958 }
9959 
9960 /*
9961  * ":return [expr]"
9962  */
9963     void
9964 ex_return(eap)
9965     exarg_T	*eap;
9966 {
9967     char_u	*arg = eap->arg;
9968     var		retvar;
9969     int		returning = FALSE;
9970 
9971     if (current_funccal == NULL)
9972     {
9973 	EMSG(_("E133: :return not inside a function"));
9974 	return;
9975     }
9976 
9977     if (eap->skip)
9978 	++emsg_skip;
9979 
9980     eap->nextcmd = NULL;
9981     if ((*arg != NUL && *arg != '|' && *arg != '\n')
9982 	    && eval0(arg, &retvar, &eap->nextcmd, !eap->skip) != FAIL)
9983     {
9984 	if (!eap->skip)
9985 	    returning = do_return(eap, FALSE, TRUE, &retvar);
9986 	else
9987 	    clear_var(&retvar);
9988     }
9989     /* It's safer to return also on error. */
9990     else if (!eap->skip)
9991     {
9992 	/*
9993 	 * Return unless the expression evaluation has been cancelled due to an
9994 	 * aborting error, an interrupt, or an exception.
9995 	 */
9996 	if (!aborting())
9997 	    returning = do_return(eap, FALSE, TRUE, NULL);
9998     }
9999 
10000     /* When skipping or the return gets pending, advance to the next command
10001      * in this line (!returning).  Otherwise, ignore the rest of the line.
10002      * Following lines will be ignored by get_func_line(). */
10003     if (returning)
10004 	eap->nextcmd = NULL;
10005     else if (eap->nextcmd == NULL)	    /* no argument */
10006 	eap->nextcmd = check_nextcmd(arg);
10007 
10008     if (eap->skip)
10009 	--emsg_skip;
10010 }
10011 
10012 /*
10013  * Return from a function.  Possibly makes the return pending.  Also called
10014  * for a pending return at the ":endtry" or after returning from an extra
10015  * do_cmdline().  "reanimate" is used in the latter case.  "is_cmd" is set
10016  * when called due to a ":return" command.  "value" may point to a variable
10017  * with the return value.  Returns TRUE when the return can be carried out,
10018  * FALSE when the return gets pending.
10019  */
10020     int
10021 do_return(eap, reanimate, is_cmd, value)
10022     exarg_T	*eap;
10023     int		reanimate;
10024     int		is_cmd;
10025     void	*value;
10026 {
10027     int		idx;
10028     struct condstack *cstack = eap->cstack;
10029 
10030     if (reanimate)
10031 	/* Undo the return. */
10032 	current_funccal->returned = FALSE;
10033 
10034     /*
10035      * Cleanup (and inactivate) conditionals, but stop when a try conditional
10036      * not in its finally clause (which then is to be executed next) is found.
10037      * In this case, make the ":return" pending for execution at the ":endtry".
10038      * Otherwise, return normally.
10039      */
10040     idx = cleanup_conditionals(eap->cstack, 0, TRUE);
10041     if (idx >= 0)
10042     {
10043 	cstack->cs_pending[idx] = CSTP_RETURN;
10044 
10045 	if (!is_cmd && !reanimate)
10046 	    /* A pending return again gets pending.  "value" points to an
10047 	     * allocated variable with the value of the original ":return"'s
10048 	     * argument if present or is NULL else. */
10049 	    cstack->cs_retvar[idx] = value;
10050 	else
10051 	{
10052 	    /* When undoing a return in order to make it pending, get the stored
10053 	     * return value. */
10054 	    if (reanimate)
10055 		value = current_funccal->retvar;
10056 
10057 	    if (value != NULL)
10058 	    {
10059 		/* Store the value of the pending return. */
10060 		if ((cstack->cs_retvar[idx] = alloc_var()) != NULL)
10061 		    *(VAR)cstack->cs_retvar[idx] = *(VAR)value;
10062 		else
10063 		    EMSG(_(e_outofmem));
10064 	    }
10065 	    else
10066 		cstack->cs_retvar[idx] = NULL;
10067 
10068 	    if (reanimate)
10069 	    {
10070 		/* The pending return value could be overwritten by a ":return"
10071 		 * without argument in a finally clause; reset the default
10072 		 * return value. */
10073 		current_funccal->retvar->var_type = VAR_NUMBER;
10074 		current_funccal->retvar->var_val.var_number = 0;
10075 	    }
10076 	}
10077 	report_make_pending(CSTP_RETURN, value);
10078     }
10079     else
10080     {
10081 	current_funccal->returned = TRUE;
10082 
10083 	/* If the return is carried out now, store the return value.  For
10084 	 * a return immediately after reanimation, the value is already
10085 	 * there. */
10086 	if (!reanimate && value != NULL)
10087 	{
10088 	    clear_var(current_funccal->retvar);
10089 	    *current_funccal->retvar = *(VAR)value;
10090 	    if (!is_cmd)
10091 		vim_free(value);
10092 	}
10093     }
10094 
10095     return idx < 0;
10096 }
10097 
10098 /*
10099  * Free the variable with a pending return value.
10100  */
10101     void
10102 discard_pending_return(retvar)
10103     void	*retvar;
10104 {
10105     /* The variable was copied from one with an undefined var_name.  So we can't
10106      * use free_var() to clear and free it. */
10107     clear_var((VAR)retvar);
10108     vim_free(retvar);
10109 }
10110 
10111 /*
10112  * Generate a return command for producing the value of "retvar".  The result
10113  * is an allocated string.  Used by report_pending() for verbose messages.
10114  */
10115     char_u *
10116 get_return_cmd(retvar)
10117     void	*retvar;
10118 {
10119     char_u	*s = IObuff;
10120 
10121     if (retvar == NULL || ((VAR)retvar)->var_type == VAR_UNKNOWN)
10122 	s = (char_u *)":return";
10123     else if (((VAR)retvar)->var_type == VAR_STRING)
10124 	sprintf((char *)IObuff, ":return \"%s\"",
10125 		((VAR)retvar)->var_val.var_string);
10126     else
10127 	sprintf((char *)IObuff, ":return %ld",
10128 		(long)(((VAR)retvar)->var_val.var_number));
10129     return vim_strsave(s);
10130 }
10131 
10132 /*
10133  * Get next function line.
10134  * Called by do_cmdline() to get the next line.
10135  * Returns allocated string, or NULL for end of function.
10136  */
10137 /* ARGSUSED */
10138     char_u *
10139 get_func_line(c, cookie, indent)
10140     int	    c;		    /* not used */
10141     void    *cookie;
10142     int	    indent;	    /* not used */
10143 {
10144     struct funccall	*fcp = (struct funccall *)cookie;
10145     char_u		*retval;
10146     garray_T		*gap;  /* growarray with function lines */
10147 
10148     /* If breakpoints have been added/deleted need to check for it. */
10149     if (fcp->dbg_tick != debug_tick)
10150     {
10151 	fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name,
10152 							       sourcing_lnum);
10153 	fcp->dbg_tick = debug_tick;
10154     }
10155 
10156     gap = &fcp->func->lines;
10157     if ((fcp->func->flags & FC_ABORT) && did_emsg && !aborted_in_try())
10158 	retval = NULL;
10159     else if (fcp->returned || fcp->linenr >= gap->ga_len)
10160 	retval = NULL;
10161     else
10162     {
10163 	retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
10164 	sourcing_lnum = fcp->linenr;
10165     }
10166 
10167     /* Did we encounter a breakpoint? */
10168     if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum)
10169     {
10170 	dbg_breakpoint(fcp->func->name, sourcing_lnum);
10171 	/* Find next breakpoint. */
10172 	fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name,
10173 							       sourcing_lnum);
10174 	fcp->dbg_tick = debug_tick;
10175     }
10176 
10177     return retval;
10178 }
10179 
10180 /*
10181  * Return TRUE if the currently active function should be ended, because a
10182  * return was encountered or an error occured.  Used inside a ":while".
10183  */
10184     int
10185 func_has_ended(cookie)
10186     void    *cookie;
10187 {
10188     struct funccall  *fcp = (struct funccall *)cookie;
10189 
10190     /* Ignore the "abort" flag if the abortion behavior has been changed due to
10191      * an error inside a try conditional. */
10192     return (((fcp->func->flags & FC_ABORT) && did_emsg && !aborted_in_try())
10193 	    || fcp->returned);
10194 }
10195 
10196 /*
10197  * return TRUE if cookie indicates a function which "abort"s on errors.
10198  */
10199     int
10200 func_has_abort(cookie)
10201     void    *cookie;
10202 {
10203     return ((struct funccall *)cookie)->func->flags & FC_ABORT;
10204 }
10205 
10206 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)
10207 typedef enum
10208 {
10209     VAR_FLAVOUR_DEFAULT,
10210     VAR_FLAVOUR_SESSION,
10211     VAR_FLAVOUR_VIMINFO
10212 } var_flavour_T;
10213 
10214 static var_flavour_T var_flavour __ARGS((char_u *varname));
10215 
10216     static var_flavour_T
10217 var_flavour(varname)
10218     char_u *varname;
10219 {
10220     char_u *p = varname;
10221 
10222     if (ASCII_ISUPPER(*p))
10223     {
10224 	while (*(++p))
10225 	    if (ASCII_ISLOWER(*p))
10226 		return VAR_FLAVOUR_SESSION;
10227 	return VAR_FLAVOUR_VIMINFO;
10228     }
10229     else
10230 	return VAR_FLAVOUR_DEFAULT;
10231 }
10232 #endif
10233 
10234 #if defined(FEAT_VIMINFO) || defined(PROTO)
10235 /*
10236  * Restore global vars that start with a capital from the viminfo file
10237  */
10238     int
10239 read_viminfo_varlist(virp, writing)
10240     vir_T	*virp;
10241     int		writing;
10242 {
10243     char_u	*tab;
10244     int		is_string = FALSE;
10245     VAR		varp = NULL;
10246     char_u	*val;
10247 
10248     if (!writing && (find_viminfo_parameter('!') != NULL))
10249     {
10250 	tab = vim_strchr(virp->vir_line + 1, '\t');
10251 	if (tab != NULL)
10252 	{
10253 	    *tab++ = '\0';	/* isolate the variable name */
10254 	    if (*tab == 'S')	/* string var */
10255 		is_string = TRUE;
10256 
10257 	    tab = vim_strchr(tab, '\t');
10258 	    if (tab != NULL)
10259 	    {
10260 		/* create a nameless variable to hold the value */
10261 		if (is_string)
10262 		{
10263 		    val = viminfo_readstring(virp,
10264 				       (int)(tab - virp->vir_line + 1), TRUE);
10265 		    if (val != NULL)
10266 			varp = alloc_string_var(val);
10267 		}
10268 		else
10269 		{
10270 		    varp = alloc_var();
10271 		    if (varp != NULL)
10272 		    {
10273 			varp->var_type = VAR_NUMBER;
10274 			varp->var_val.var_number = atol((char *)tab + 1);
10275 		    }
10276 		}
10277 		/* assign the value to the variable */
10278 		if (varp != NULL)
10279 		{
10280 		    set_var(virp->vir_line + 1, varp);
10281 		    free_var(varp);
10282 		}
10283 	    }
10284 	}
10285     }
10286 
10287     return viminfo_readline(virp);
10288 }
10289 
10290 /*
10291  * Write global vars that start with a capital to the viminfo file
10292  */
10293     void
10294 write_viminfo_varlist(fp)
10295     FILE    *fp;
10296 {
10297     garray_T	*gap = &variables;		/* global variable */
10298     VAR		this_var;
10299     int		i;
10300 
10301     if (find_viminfo_parameter('!') == NULL)
10302 	return;
10303 
10304     fprintf(fp, _("\n# global variables:\n"));
10305     for (i = gap->ga_len; --i >= 0; )
10306     {
10307 	this_var = &VAR_GAP_ENTRY(i, gap);
10308 	if (this_var->var_name != NULL
10309 		&& var_flavour(this_var->var_name) == VAR_FLAVOUR_VIMINFO)
10310 	{
10311 	    fprintf(fp, "!%s\t%s\t", this_var->var_name,
10312 			  (this_var->var_type == VAR_STRING) ? "STR" : "NUM");
10313 	    viminfo_writestring(fp, get_var_string(this_var));
10314 	}
10315     }
10316 }
10317 #endif
10318 
10319 #if defined(FEAT_SESSION) || defined(PROTO)
10320     int
10321 store_session_globals(fd)
10322     FILE	*fd;
10323 {
10324     garray_T	*gap = &variables;		/* global variable */
10325     VAR		this_var;
10326     int		i;
10327     char_u	*p, *t;
10328 
10329     for (i = gap->ga_len; --i >= 0; )
10330     {
10331 	this_var = &VAR_GAP_ENTRY(i, gap);
10332 	if (this_var->var_name != NULL)
10333 	{
10334 	    if (var_flavour(this_var->var_name) == VAR_FLAVOUR_SESSION)
10335 	    {
10336 		/* Escapse special characters with a backslash.  Turn a LF and
10337 		 * CR into \n and \r. */
10338 		p = vim_strsave_escaped(get_var_string(this_var),
10339 							(char_u *)"\\\"\n\r");
10340 		if (p == NULL)	    /* out of memory */
10341 		    continue;
10342 		for (t = p; *t != NUL; ++t)
10343 		    if (*t == '\n')
10344 			*t = 'n';
10345 		    else if (*t == '\r')
10346 			*t = 'r';
10347 		if ((fprintf(fd, "let %s = %c%s%c",
10348 			    this_var->var_name,
10349 			    (this_var->var_type == VAR_STRING) ? '"' : ' ',
10350 			    p,
10351 			    (this_var->var_type == VAR_STRING) ? '"' : ' ') < 0)
10352 			|| put_eol(fd) == FAIL)
10353 		{
10354 		    vim_free(p);
10355 		    return FAIL;
10356 		}
10357 		vim_free(p);
10358 	    }
10359 
10360 	}
10361     }
10362     return OK;
10363 }
10364 #endif
10365 
10366 #endif /* FEAT_EVAL */
10367 
10368 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO)
10369 
10370 
10371 #ifdef WIN3264
10372 /*
10373  * Functions for ":8" filename modifier: get 8.3 version of a filename.
10374  */
10375 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen));
10376 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen));
10377 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen));
10378 
10379 /*
10380  * Get the short pathname of a file.
10381  * Returns 1 on success. *fnamelen is 0 for nonexistant path.
10382  */
10383     static int
10384 get_short_pathname(fnamep, bufp, fnamelen)
10385     char_u	**fnamep;
10386     char_u	**bufp;
10387     int		*fnamelen;
10388 {
10389     int		l,len;
10390     char_u	*newbuf;
10391 
10392     len = *fnamelen;
10393 
10394     l = GetShortPathName(*fnamep, *fnamep, len);
10395     if (l > len - 1)
10396     {
10397 	/* If that doesn't work (not enough space), then save the string
10398 	 * and try again with a new buffer big enough
10399 	 */
10400 	newbuf = vim_strnsave(*fnamep, l);
10401 	if (newbuf == NULL)
10402 	    return 0;
10403 
10404 	vim_free(*bufp);
10405 	*fnamep = *bufp = newbuf;
10406 
10407 	l = GetShortPathName(*fnamep,*fnamep,l+1);
10408 
10409 	/* Really should always succeed, as the buffer is big enough */
10410     }
10411 
10412     *fnamelen = l;
10413     return 1;
10414 }
10415 
10416 /*
10417  * Create a short path name.  Returns the length of the buffer it needs.
10418  * Doesn't copy over the end of the buffer passed in.
10419  */
10420     static int
10421 shortpath_for_invalid_fname(fname, bufp, fnamelen)
10422     char_u	**fname;
10423     char_u	**bufp;
10424     int		*fnamelen;
10425 {
10426     char_u	*s, *p, *pbuf2, *pbuf3;
10427     char_u	ch;
10428     int		l,len,len2,plen,slen;
10429 
10430     /* Make a copy */
10431     len2 = *fnamelen;
10432     pbuf2 = vim_strnsave(*fname, len2);
10433     pbuf3 = NULL;
10434 
10435     s = pbuf2 + len2 - 1; /* Find the end */
10436     slen = 1;
10437     plen = len2;
10438 
10439     l = 0;
10440     if (vim_ispathsep(*s))
10441     {
10442 	--s;
10443 	++slen;
10444 	--plen;
10445     }
10446 
10447     do
10448     {
10449 	/* Go back one path-seperator */
10450 	while (s > pbuf2 && !vim_ispathsep(*s))
10451 	{
10452 	    --s;
10453 	    ++slen;
10454 	    --plen;
10455 	}
10456 	if (s <= pbuf2)
10457 	    break;
10458 
10459 	/* Remeber the character that is about to be blatted */
10460 	ch = *s;
10461 	*s = 0; /* get_short_pathname requires a null-terminated string */
10462 
10463 	/* Try it in situ */
10464 	p = pbuf2;
10465 	if (!get_short_pathname(&p, &pbuf3, &plen))
10466 	{
10467 	    vim_free(pbuf2);
10468 	    return -1;
10469 	}
10470 	*s = ch;    /* Preserve the string */
10471     } while (plen == 0);
10472 
10473     if (plen > 0)
10474     {
10475 	/* Remeber the length of the new string.  */
10476 	*fnamelen = len = plen + slen;
10477 	vim_free(*bufp);
10478 	if (len > len2)
10479 	{
10480 	    /* If there's not enough space in the currently allocated string,
10481 	     * then copy it to a buffer big enough.
10482 	     */
10483 	    *fname= *bufp = vim_strnsave(p, len);
10484 	    if (*fname == NULL)
10485 		return -1;
10486 	}
10487 	else
10488 	{
10489 	    /* Transfer pbuf2 to being the main buffer  (it's big enough) */
10490 	    *fname = *bufp = pbuf2;
10491 	    if (p != pbuf2)
10492 		strncpy(*fname, p, plen);
10493 	    pbuf2 = NULL;
10494 	}
10495 	/* Concat the next bit */
10496 	strncpy(*fname + plen, s, slen);
10497 	(*fname)[len] = '\0';
10498     }
10499     vim_free(pbuf3);
10500     vim_free(pbuf2);
10501     return 0;
10502 }
10503 
10504 /*
10505  * Get a pathname for a partial path.
10506  */
10507     static int
10508 shortpath_for_partial(fnamep, bufp, fnamelen)
10509     char_u	**fnamep;
10510     char_u	**bufp;
10511     int		*fnamelen;
10512 {
10513     int		sepcount, len, tflen;
10514     char_u	*p;
10515     char_u	*pbuf, *tfname;
10516     int		hasTilde;
10517 
10518     /* Count up the path seperators from the RHS.. so we know which part
10519      * of the path to return.
10520      */
10521     sepcount = 0;
10522     for (p = *fnamep + *fnamelen - 1; p >= *fnamep; --p)
10523 	if (vim_ispathsep(*p))
10524 	    ++sepcount;
10525 
10526     /* Need full path first (use expand_env() to remove a "~/") */
10527     hasTilde = (**fnamep == '~');
10528     if (hasTilde)
10529 	pbuf = tfname = expand_env_save(*fnamep);
10530     else
10531 	pbuf = tfname = FullName_save(*fnamep, FALSE);
10532 
10533     len = tflen = STRLEN(tfname);
10534 
10535     if (!get_short_pathname(&tfname, &pbuf, &len))
10536 	return -1;
10537 
10538     if (len == 0)
10539     {
10540 	/* Don't have a valid filename, so shorten the rest of the
10541 	 * path if we can. This CAN give us invalid 8.3 filenames, but
10542 	 * there's not a lot of point in guessing what it might be.
10543 	 */
10544 	len = tflen;
10545 	if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1)
10546 	    return -1;
10547     }
10548 
10549     /* Count the paths backward to find the beginning of the desired string. */
10550     for (p = tfname + len - 1; p >= tfname; --p)
10551 	if (vim_ispathsep(*p))
10552 	{
10553 	    if (sepcount == 0 || (hasTilde && sepcount == 1))
10554 		break;
10555 	    else
10556 		sepcount --;
10557 	}
10558     if (hasTilde)
10559     {
10560 	--p;
10561 	if (p >= tfname)
10562 	    *p = '~';
10563 	else
10564 	    return -1;
10565     }
10566     else
10567 	++p;
10568 
10569     /* Copy in the string - p indexes into tfname - allocated at pbuf */
10570     vim_free(*bufp);
10571     *fnamelen = (int)STRLEN(p);
10572     *bufp = pbuf;
10573     *fnamep = p;
10574 
10575     return 0;
10576 }
10577 #endif /* WIN3264 */
10578 
10579 /*
10580  * Adjust a filename, according to a string of modifiers.
10581  * *fnamep must be NUL terminated when called.  When returning, the length is
10582  * determined by *fnamelen.
10583  * Returns valid flags.
10584  * When there is an error, *fnamep is set to NULL.
10585  */
10586     int
10587 modify_fname(src, usedlen, fnamep, bufp, fnamelen)
10588     char_u	*src;		/* string with modifiers */
10589     int		*usedlen;	/* characters after src that are used */
10590     char_u	**fnamep;	/* file name so far */
10591     char_u	**bufp;		/* buffer for allocated file name or NULL */
10592     int		*fnamelen;	/* length of fnamep */
10593 {
10594     int		valid = 0;
10595     char_u	*tail;
10596     char_u	*s, *p, *pbuf;
10597     char_u	dirname[MAXPATHL];
10598     int		c;
10599     int		has_fullname = 0;
10600 #ifdef WIN3264
10601     int		has_shortname = 0;
10602 #endif
10603 
10604 repeat:
10605     /* ":p" - full path/file_name */
10606     if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p')
10607     {
10608 	has_fullname = 1;
10609 
10610 	valid |= VALID_PATH;
10611 	*usedlen += 2;
10612 
10613 	/* Expand "~/path" for all systems and "~user/path" for Unix and VMS */
10614 	if ((*fnamep)[0] == '~'
10615 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME))
10616 		&& ((*fnamep)[1] == '/'
10617 # ifdef BACKSLASH_IN_FILENAME
10618 		    || (*fnamep)[1] == '\\'
10619 # endif
10620 		    || (*fnamep)[1] == NUL)
10621 
10622 #endif
10623 	   )
10624 	{
10625 	    *fnamep = expand_env_save(*fnamep);
10626 	    vim_free(*bufp);	/* free any allocated file name */
10627 	    *bufp = *fnamep;
10628 	    if (*fnamep == NULL)
10629 		return -1;
10630 	}
10631 
10632 	/* When "/." or "/.." is used: force expansion to get rid of it. */
10633 	for (p = *fnamep; *p != NUL; ++p)
10634 	{
10635 	    if (vim_ispathsep(*p)
10636 		    && p[1] == '.'
10637 		    && (p[2] == NUL
10638 			|| vim_ispathsep(p[2])
10639 			|| (p[2] == '.'
10640 			    && (p[3] == NUL || vim_ispathsep(p[3])))))
10641 		break;
10642 	}
10643 
10644 	/* FullName_save() is slow, don't use it when not needed. */
10645 	if (*p != NUL || !vim_isAbsName(*fnamep))
10646 	{
10647 	    *fnamep = FullName_save(*fnamep, *p != NUL);
10648 	    vim_free(*bufp);	/* free any allocated file name */
10649 	    *bufp = *fnamep;
10650 	    if (*fnamep == NULL)
10651 		return -1;
10652 	}
10653 
10654 	/* Append a path separator to a directory. */
10655 	if (mch_isdir(*fnamep))
10656 	{
10657 	    /* Make room for one or two extra characters. */
10658 	    *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2);
10659 	    vim_free(*bufp);	/* free any allocated file name */
10660 	    *bufp = *fnamep;
10661 	    if (*fnamep == NULL)
10662 		return -1;
10663 	    add_pathsep(*fnamep);
10664 	}
10665     }
10666 
10667     /* ":." - path relative to the current directory */
10668     /* ":~" - path relative to the home directory */
10669     /* ":8" - shortname path - postponed till after */
10670     while (src[*usedlen] == ':'
10671 		  && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8'))
10672     {
10673 	*usedlen += 2;
10674 	if (c == '8')
10675 	{
10676 #ifdef WIN3264
10677 	    has_shortname = 1; /* Postpone this. */
10678 #endif
10679 	    continue;
10680 	}
10681 	pbuf = NULL;
10682 	/* Need full path first (use expand_env() to remove a "~/") */
10683 	if (!has_fullname)
10684 	{
10685 	    if (c == '.' && **fnamep == '~')
10686 		p = pbuf = expand_env_save(*fnamep);
10687 	    else
10688 		p = pbuf = FullName_save(*fnamep, FALSE);
10689 	}
10690 	else
10691 	    p = *fnamep;
10692 
10693 	has_fullname = 0;
10694 
10695 	if (p != NULL)
10696 	{
10697 	    if (c == '.')
10698 	    {
10699 		mch_dirname(dirname, MAXPATHL);
10700 		s = shorten_fname(p, dirname);
10701 		if (s != NULL)
10702 		{
10703 		    *fnamep = s;
10704 		    if (pbuf != NULL)
10705 		    {
10706 			vim_free(*bufp);   /* free any allocated file name */
10707 			*bufp = pbuf;
10708 			pbuf = NULL;
10709 		    }
10710 		}
10711 	    }
10712 	    else
10713 	    {
10714 		home_replace(NULL, p, dirname, MAXPATHL, TRUE);
10715 		/* Only replace it when it starts with '~' */
10716 		if (*dirname == '~')
10717 		{
10718 		    s = vim_strsave(dirname);
10719 		    if (s != NULL)
10720 		    {
10721 			*fnamep = s;
10722 			vim_free(*bufp);
10723 			*bufp = s;
10724 		    }
10725 		}
10726 	    }
10727 	    vim_free(pbuf);
10728 	}
10729     }
10730 
10731     tail = gettail(*fnamep);
10732     *fnamelen = (int)STRLEN(*fnamep);
10733 
10734     /* ":h" - head, remove "/file_name", can be repeated  */
10735     /* Don't remove the first "/" or "c:\" */
10736     while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h')
10737     {
10738 	valid |= VALID_HEAD;
10739 	*usedlen += 2;
10740 	s = get_past_head(*fnamep);
10741 	while (tail > s && vim_ispathsep(tail[-1]))
10742 	    --tail;
10743 	*fnamelen = (int)(tail - *fnamep);
10744 #ifdef VMS
10745 	if (*fnamelen > 0)
10746 	    *fnamelen += 1; /* the path separator is part of the path */
10747 #endif
10748 	while (tail > s && !vim_ispathsep(tail[-1]))
10749 	    --tail;
10750     }
10751 
10752     /* ":8" - shortname  */
10753     if (src[*usedlen] == ':' && src[*usedlen + 1] == '8')
10754     {
10755 	*usedlen += 2;
10756 #ifdef WIN3264
10757 	has_shortname = 1;
10758 #endif
10759     }
10760 
10761 #ifdef WIN3264
10762     /* Check shortname after we have done 'heads' and before we do 'tails'
10763      */
10764     if (has_shortname)
10765     {
10766 	pbuf = NULL;
10767 	/* Copy the string if it is shortened by :h */
10768 	if (*fnamelen < (int)STRLEN(*fnamep))
10769 	{
10770 	    p = vim_strnsave(*fnamep, *fnamelen);
10771 	    if (p == 0)
10772 		return -1;
10773 	    vim_free(*bufp);
10774 	    *bufp = *fnamep = p;
10775 	}
10776 
10777 	/* Split into two implementations - makes it easier.  First is where
10778 	 * there isn't a full name already, second is where there is.
10779 	 */
10780 	if (!has_fullname && !vim_isAbsName(*fnamep))
10781 	{
10782 	    if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1)
10783 		return -1;
10784 	}
10785 	else
10786 	{
10787 	    int		l;
10788 
10789 	    /* Simple case, already have the full-name
10790 	     * Nearly always shorter, so try first time. */
10791 	    l = *fnamelen;
10792 	    if (!get_short_pathname(fnamep, bufp, &l))
10793 		return -1;
10794 
10795 	    if (l == 0)
10796 	    {
10797 		/* Couldn't find the filename.. search the paths.
10798 		 */
10799 		l = *fnamelen;
10800 		if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1)
10801 		    return -1;
10802 	    }
10803 	    *fnamelen = l;
10804 	}
10805     }
10806 #endif /* WIN3264 */
10807 
10808     /* ":t" - tail, just the basename */
10809     if (src[*usedlen] == ':' && src[*usedlen + 1] == 't')
10810     {
10811 	*usedlen += 2;
10812 	*fnamelen -= (int)(tail - *fnamep);
10813 	*fnamep = tail;
10814     }
10815 
10816     /* ":e" - extension, can be repeated */
10817     /* ":r" - root, without extension, can be repeated */
10818     while (src[*usedlen] == ':'
10819 	    && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r'))
10820     {
10821 	/* find a '.' in the tail:
10822 	 * - for second :e: before the current fname
10823 	 * - otherwise: The last '.'
10824 	 */
10825 	if (src[*usedlen + 1] == 'e' && *fnamep > tail)
10826 	    s = *fnamep - 2;
10827 	else
10828 	    s = *fnamep + *fnamelen - 1;
10829 	for ( ; s > tail; --s)
10830 	    if (s[0] == '.')
10831 		break;
10832 	if (src[*usedlen + 1] == 'e')		/* :e */
10833 	{
10834 	    if (s > tail)
10835 	    {
10836 		*fnamelen += (int)(*fnamep - (s + 1));
10837 		*fnamep = s + 1;
10838 #ifdef VMS
10839 		/* cut version from the extension */
10840 		s = *fnamep + *fnamelen - 1;
10841 		for ( ; s > *fnamep; --s)
10842 		    if (s[0] == ';')
10843 			break;
10844 		if (s > *fnamep)
10845 		    *fnamelen = s - *fnamep;
10846 #endif
10847 	    }
10848 	    else if (*fnamep <= tail)
10849 		*fnamelen = 0;
10850 	}
10851 	else				/* :r */
10852 	{
10853 	    if (s > tail)	/* remove one extension */
10854 		*fnamelen = (int)(s - *fnamep);
10855 	}
10856 	*usedlen += 2;
10857     }
10858 
10859     /* ":s?pat?foo?" - substitute */
10860     /* ":gs?pat?foo?" - global substitute */
10861     if (src[*usedlen] == ':'
10862 	    && (src[*usedlen + 1] == 's'
10863 		|| (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's')))
10864     {
10865 	char_u	    *str;
10866 	char_u	    *pat;
10867 	char_u	    *sub;
10868 	int	    sep;
10869 	char_u	    *flags;
10870 	int	    didit = FALSE;
10871 
10872 	flags = (char_u *)"";
10873 	s = src + *usedlen + 2;
10874 	if (src[*usedlen + 1] == 'g')
10875 	{
10876 	    flags = (char_u *)"g";
10877 	    ++s;
10878 	}
10879 
10880 	sep = *s++;
10881 	if (sep)
10882 	{
10883 	    /* find end of pattern */
10884 	    p = vim_strchr(s, sep);
10885 	    if (p != NULL)
10886 	    {
10887 		pat = vim_strnsave(s, (int)(p - s));
10888 		if (pat != NULL)
10889 		{
10890 		    s = p + 1;
10891 		    /* find end of substitution */
10892 		    p = vim_strchr(s, sep);
10893 		    if (p != NULL)
10894 		    {
10895 			sub = vim_strnsave(s, (int)(p - s));
10896 			str = vim_strnsave(*fnamep, *fnamelen);
10897 			if (sub != NULL && str != NULL)
10898 			{
10899 			    *usedlen = (int)(p + 1 - src);
10900 			    s = do_string_sub(str, pat, sub, flags);
10901 			    if (s != NULL)
10902 			    {
10903 				*fnamep = s;
10904 				*fnamelen = (int)STRLEN(s);
10905 				vim_free(*bufp);
10906 				*bufp = s;
10907 				didit = TRUE;
10908 			    }
10909 			}
10910 			vim_free(sub);
10911 			vim_free(str);
10912 		    }
10913 		    vim_free(pat);
10914 		}
10915 	    }
10916 	    /* after using ":s", repeat all the modifiers */
10917 	    if (didit)
10918 		goto repeat;
10919 	}
10920     }
10921 
10922     return valid;
10923 }
10924 
10925 /*
10926  * Perform a substitution on "str" with pattern "pat" and substitute "sub".
10927  * "flags" can be "g" to do a global substitute.
10928  * Returns an allocated string, NULL for error.
10929  */
10930     char_u *
10931 do_string_sub(str, pat, sub, flags)
10932     char_u	*str;
10933     char_u	*pat;
10934     char_u	*sub;
10935     char_u	*flags;
10936 {
10937     int		sublen;
10938     regmatch_T	regmatch;
10939     int		i;
10940     int		do_all;
10941     char_u	*tail;
10942     garray_T	ga;
10943     char_u	*ret;
10944     char_u	*save_cpo;
10945 
10946     /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */
10947     save_cpo = p_cpo;
10948     p_cpo = (char_u *)"";
10949 
10950     ga_init2(&ga, 1, 200);
10951 
10952     do_all = (flags[0] == 'g');
10953 
10954     regmatch.rm_ic = p_ic;
10955     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
10956     if (regmatch.regprog != NULL)
10957     {
10958 	tail = str;
10959 	while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
10960 	{
10961 	    /*
10962 	     * Get some space for a temporary buffer to do the substitution
10963 	     * into.  It will contain:
10964 	     * - The text up to where the match is.
10965 	     * - The substituted text.
10966 	     * - The text after the match.
10967 	     */
10968 	    sublen = vim_regsub(&regmatch, sub, tail, FALSE, TRUE, FALSE);
10969 	    if (ga_grow(&ga, (int)(STRLEN(tail) + sublen -
10970 			    (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
10971 	    {
10972 		ga_clear(&ga);
10973 		break;
10974 	    }
10975 
10976 	    /* copy the text up to where the match is */
10977 	    i = (int)(regmatch.startp[0] - tail);
10978 	    mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
10979 	    /* add the substituted text */
10980 	    (void)vim_regsub(&regmatch, sub, (char_u *)ga.ga_data
10981 					  + ga.ga_len + i, TRUE, TRUE, FALSE);
10982 	    ga.ga_len += i + sublen - 1;
10983 	    ga.ga_room -= i + sublen - 1;
10984 	    /* avoid getting stuck on a match with an empty string */
10985 	    if (tail == regmatch.endp[0])
10986 	    {
10987 		if (*tail == NUL)
10988 		    break;
10989 		*((char_u *)ga.ga_data + ga.ga_len) = *tail++;
10990 		++ga.ga_len;
10991 		--ga.ga_room;
10992 	    }
10993 	    else
10994 	    {
10995 		tail = regmatch.endp[0];
10996 		if (*tail == NUL)
10997 		    break;
10998 	    }
10999 	    if (!do_all)
11000 		break;
11001 	}
11002 
11003 	if (ga.ga_data != NULL)
11004 	    STRCPY((char *)ga.ga_data + ga.ga_len, tail);
11005 
11006 	vim_free(regmatch.regprog);
11007     }
11008 
11009     ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
11010     ga_clear(&ga);
11011     p_cpo = save_cpo;
11012 
11013     return ret;
11014 }
11015 
11016 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */
11017