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