xref: /vim-8.2.3635/src/eval.c (revision 69a7cb47)
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 
3789 /*
3790  * "libcall()" function
3791  */
3792     static void
3793 f_libcall(argvars, retvar)
3794     VAR		argvars;
3795     VAR		retvar;
3796 {
3797     libcall_common(argvars, retvar, VAR_STRING);
3798 }
3799 
3800 /*
3801  * "libcallnr()" function
3802  */
3803     static void
3804 f_libcallnr(argvars, retvar)
3805     VAR		argvars;
3806     VAR		retvar;
3807 {
3808     libcall_common(argvars, retvar, VAR_NUMBER);
3809 }
3810 
3811     static void
3812 libcall_common(argvars, retvar, type)
3813     VAR		argvars;
3814     VAR		retvar;
3815     int		type;
3816 {
3817 #ifdef FEAT_LIBCALL
3818     char_u		*string_in;
3819     char_u		**string_result;
3820     int			nr_result;
3821 #endif
3822 
3823     retvar->var_type = type;
3824     if (type == VAR_NUMBER)
3825 	retvar->var_val.var_number = 0;
3826     else
3827 	retvar->var_val.var_string = NULL;
3828 
3829     if (check_restricted() || check_secure())
3830 	return;
3831 
3832 #ifdef FEAT_LIBCALL
3833     /* The first two args must be strings, otherwise its meaningless */
3834     if (argvars[0].var_type == VAR_STRING && argvars[1].var_type == VAR_STRING)
3835     {
3836 	if (argvars[2].var_type == VAR_NUMBER)
3837 	    string_in = NULL;
3838 	else
3839 	    string_in = argvars[2].var_val.var_string;
3840 	if (type == VAR_NUMBER)
3841 	    string_result = NULL;
3842 	else
3843 	    string_result = &retvar->var_val.var_string;
3844 	if (mch_libcall(argvars[0].var_val.var_string,
3845 			     argvars[1].var_val.var_string,
3846 			     string_in,
3847 			     argvars[2].var_val.var_number,
3848 			     string_result,
3849 			     &nr_result) == OK
3850 		&& type == VAR_NUMBER)
3851 	    retvar->var_val.var_number = nr_result;
3852     }
3853 #endif
3854 }
3855 
3856 /*
3857  * "delete()" function
3858  */
3859     static void
3860 f_delete(argvars, retvar)
3861     VAR		argvars;
3862     VAR		retvar;
3863 {
3864     if (check_restricted() || check_secure())
3865 	retvar->var_val.var_number = -1;
3866     else
3867 	retvar->var_val.var_number = mch_remove(get_var_string(&argvars[0]));
3868 }
3869 
3870 /*
3871  * "did_filetype()" function
3872  */
3873 /*ARGSUSED*/
3874     static void
3875 f_did_filetype(argvars, retvar)
3876     VAR		argvars;
3877     VAR		retvar;
3878 {
3879 #ifdef FEAT_AUTOCMD
3880     retvar->var_val.var_number = did_filetype;
3881 #else
3882     retvar->var_val.var_number = 0;
3883 #endif
3884 }
3885 
3886 /*
3887  * "escape({string}, {chars})" function
3888  */
3889     static void
3890 f_escape(argvars, retvar)
3891     VAR		argvars;
3892     VAR		retvar;
3893 {
3894     char_u	buf[NUMBUFLEN];
3895 
3896     retvar->var_val.var_string =
3897 	vim_strsave_escaped(get_var_string(&argvars[0]),
3898 		get_var_string_buf(&argvars[1], buf));
3899     retvar->var_type = VAR_STRING;
3900 }
3901 
3902 /*
3903  * "eventhandler()" function
3904  */
3905 /*ARGSUSED*/
3906     static void
3907 f_eventhandler(argvars, retvar)
3908     VAR		argvars;
3909     VAR		retvar;
3910 {
3911     retvar->var_val.var_number = vgetc_busy;
3912 }
3913 
3914 /*
3915  * "executable()" function
3916  */
3917     static void
3918 f_executable(argvars, retvar)
3919     VAR		argvars;
3920     VAR		retvar;
3921 {
3922     retvar->var_val.var_number = mch_can_exe(get_var_string(&argvars[0]));
3923 }
3924 
3925 /*
3926  * "exists()" function
3927  */
3928     static void
3929 f_exists(argvars, retvar)
3930     VAR		argvars;
3931     VAR		retvar;
3932 {
3933     char_u	*p;
3934     char_u	*name;
3935     int		n = FALSE;
3936     int		len = 0;
3937 
3938     p = get_var_string(&argvars[0]);
3939     if (*p == '$')			/* environment variable */
3940     {
3941 	/* first try "normal" environment variables (fast) */
3942 	if (mch_getenv(p + 1) != NULL)
3943 	    n = TRUE;
3944 	else
3945 	{
3946 	    /* try expanding things like $VIM and ${HOME} */
3947 	    p = expand_env_save(p);
3948 	    if (p != NULL && *p != '$')
3949 		n = TRUE;
3950 	    vim_free(p);
3951 	}
3952     }
3953     else if (*p == '&' || *p == '+')			/* option */
3954 	n = (get_option_var(&p, NULL, TRUE) == OK);
3955     else if (*p == '*')			/* internal or user defined function */
3956     {
3957 	++p;
3958 	p = trans_function_name(&p, FALSE, TRUE);
3959 	if (p != NULL)
3960 	{
3961 	    if (ASCII_ISUPPER(*p) || p[0] == K_SPECIAL)
3962 		n = (find_func(p) != NULL);
3963 	    else if (ASCII_ISLOWER(*p))
3964 		n = (find_internal_func(p) >= 0);
3965 	    vim_free(p);
3966 	}
3967     }
3968     else if (*p == ':')
3969     {
3970 	n = cmd_exists(p + 1);
3971     }
3972     else if (*p == '#')
3973     {
3974 #ifdef FEAT_AUTOCMD
3975 	name = p + 1;
3976 	p = vim_strchr(name, '#');
3977 	if (p != NULL)
3978 	    n = au_exists(name, p, p + 1);
3979 	else
3980 	    n = au_exists(name, name + STRLEN(name), NULL);
3981 #endif
3982     }
3983     else				/* internal variable */
3984     {
3985 #ifdef FEAT_MAGIC_BRACES
3986 	char_u	*expr_start;
3987 	char_u	*expr_end;
3988 	char_u  *temp_string = NULL;
3989 	char_u	*s;
3990 #endif
3991 	name = p;
3992 
3993 #ifdef FEAT_MAGIC_BRACES
3994 	/* Find the end of the name. */
3995 	s = find_name_end(name, &expr_start, &expr_end);
3996 	if (expr_start != NULL)
3997 	{
3998 	    temp_string = make_expanded_name(name, expr_start, expr_end, s);
3999 	    if (temp_string != NULL)
4000 	    {
4001 		len = STRLEN(temp_string);
4002 		name = temp_string;
4003 	    }
4004 	}
4005 #endif
4006 	if (len == 0)
4007 	    len = get_id_len(&p);
4008 	if (len != 0)
4009 	    n = (get_var_var(name, len, NULL) == OK);
4010 
4011 #ifdef FEAT_MAGIC_BRACES
4012 	vim_free(temp_string);
4013 #endif
4014     }
4015 
4016     retvar->var_val.var_number = n;
4017 }
4018 
4019 /*
4020  * "expand()" function
4021  */
4022     static void
4023 f_expand(argvars, retvar)
4024     VAR		argvars;
4025     VAR		retvar;
4026 {
4027     char_u	*s;
4028     int		len;
4029     char_u	*errormsg;
4030     int		flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
4031     expand_T	xpc;
4032 
4033     retvar->var_type = VAR_STRING;
4034     s = get_var_string(&argvars[0]);
4035     if (*s == '%' || *s == '#' || *s == '<')
4036     {
4037 	++emsg_off;
4038 	retvar->var_val.var_string = eval_vars(s, &len, NULL, &errormsg, s);
4039 	--emsg_off;
4040     }
4041     else
4042     {
4043 	/* When the optional second argument is non-zero, don't remove matches
4044 	 * for 'suffixes' and 'wildignore' */
4045 	if (argvars[1].var_type != VAR_UNKNOWN && get_var_number(&argvars[1]))
4046 	    flags |= WILD_KEEP_ALL;
4047 	ExpandInit(&xpc);
4048 	xpc.xp_context = EXPAND_FILES;
4049 	retvar->var_val.var_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL);
4050 	ExpandCleanup(&xpc);
4051     }
4052 }
4053 
4054 /*
4055  * "filereadable()" function
4056  */
4057     static void
4058 f_filereadable(argvars, retvar)
4059     VAR		argvars;
4060     VAR		retvar;
4061 {
4062     FILE	*fd;
4063     char_u	*p;
4064     int		n;
4065 
4066     p = get_var_string(&argvars[0]);
4067     if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL)
4068     {
4069 	n = TRUE;
4070 	fclose(fd);
4071     }
4072     else
4073 	n = FALSE;
4074 
4075     retvar->var_val.var_number = n;
4076 }
4077 
4078 /*
4079  * return 0 for not writable, 1 for writable file, 2 for a dir which we have
4080  * rights to write into.
4081  */
4082     static void
4083 f_filewritable(argvars, retvar)
4084     VAR		argvars;
4085     VAR		retvar;
4086 {
4087     char_u	*p;
4088     int		retval = 0;
4089 #if defined(UNIX) || defined(VMS)
4090     int		perm = 0;
4091 #endif
4092 
4093     p = get_var_string(&argvars[0]);
4094 #if defined(UNIX) || defined(VMS)
4095     perm = mch_getperm(p);
4096 #endif
4097 #ifndef MACOS_CLASSIC /* TODO: get either mch_writable or mch_access */
4098     if (
4099 # ifdef WIN3264
4100 	    mch_writable(p) &&
4101 # else
4102 # if defined(UNIX) || defined(VMS)
4103 	    (perm & 0222) &&
4104 #  endif
4105 # endif
4106 	    mch_access((char *)p, W_OK) == 0
4107        )
4108 #endif
4109     {
4110 	++retval;
4111 	if (mch_isdir(p))
4112 	    ++retval;
4113     }
4114     retvar->var_val.var_number = retval;
4115 }
4116 
4117 /*
4118  * "fnamemodify({fname}, {mods})" function
4119  */
4120     static void
4121 f_fnamemodify(argvars, retvar)
4122     VAR		argvars;
4123     VAR		retvar;
4124 {
4125     char_u	*fname;
4126     char_u	*mods;
4127     int		usedlen = 0;
4128     int		len;
4129     char_u	*fbuf = NULL;
4130     char_u	buf[NUMBUFLEN];
4131 
4132     fname = get_var_string(&argvars[0]);
4133     mods = get_var_string_buf(&argvars[1], buf);
4134     len = (int)STRLEN(fname);
4135 
4136     (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
4137 
4138     retvar->var_type = VAR_STRING;
4139     if (fname == NULL)
4140 	retvar->var_val.var_string = NULL;
4141     else
4142 	retvar->var_val.var_string = vim_strnsave(fname, len);
4143     vim_free(fbuf);
4144 }
4145 
4146 /*
4147  * "foldclosed()" function
4148  */
4149     static void
4150 f_foldclosed(argvars, retvar)
4151     VAR		argvars;
4152     VAR		retvar;
4153 {
4154     foldclosed_both(argvars, retvar, FALSE);
4155 }
4156 
4157 /*
4158  * "foldclosedend()" function
4159  */
4160     static void
4161 f_foldclosedend(argvars, retvar)
4162     VAR		argvars;
4163     VAR		retvar;
4164 {
4165     foldclosed_both(argvars, retvar, TRUE);
4166 }
4167 
4168 /*
4169  * "foldclosed()" function
4170  */
4171     static void
4172 foldclosed_both(argvars, retvar, end)
4173     VAR		argvars;
4174     VAR		retvar;
4175     int		end;
4176 {
4177 #ifdef FEAT_FOLDING
4178     linenr_T	lnum;
4179     linenr_T	first, last;
4180 
4181     lnum = get_var_lnum(argvars);
4182     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
4183     {
4184 	if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL))
4185 	{
4186 	    if (end)
4187 		retvar->var_val.var_number = (varnumber_T)last;
4188 	    else
4189 		retvar->var_val.var_number = (varnumber_T)first;
4190 	    return;
4191 	}
4192     }
4193 #endif
4194     retvar->var_val.var_number = -1;
4195 }
4196 
4197 /*
4198  * "foldlevel()" function
4199  */
4200     static void
4201 f_foldlevel(argvars, retvar)
4202     VAR		argvars;
4203     VAR		retvar;
4204 {
4205 #ifdef FEAT_FOLDING
4206     linenr_T	lnum;
4207 
4208     lnum = get_var_lnum(argvars);
4209     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
4210 	retvar->var_val.var_number = foldLevel(lnum);
4211     else
4212 #endif
4213 	retvar->var_val.var_number = 0;
4214 }
4215 
4216 /*
4217  * "foldtext()" function
4218  */
4219 /*ARGSUSED*/
4220     static void
4221 f_foldtext(argvars, retvar)
4222     VAR		argvars;
4223     VAR		retvar;
4224 {
4225 #ifdef FEAT_FOLDING
4226     linenr_T	lnum;
4227     char_u	*s;
4228     char_u	*r;
4229     int		len;
4230     char	*txt;
4231 #endif
4232 
4233     retvar->var_type = VAR_STRING;
4234     retvar->var_val.var_string = NULL;
4235 #ifdef FEAT_FOLDING
4236     if ((linenr_T)vimvars[VV_FOLDSTART].val > 0
4237 	    && (linenr_T)vimvars[VV_FOLDEND].val <= curbuf->b_ml.ml_line_count
4238 	    && vimvars[VV_FOLDDASHES].val != NULL)
4239     {
4240 	/* Find first non-empty line in the fold. */
4241 	lnum = (linenr_T)vimvars[VV_FOLDSTART].val;
4242 	while (lnum < (linenr_T)vimvars[VV_FOLDEND].val)
4243 	{
4244 	    if (!linewhite(lnum))
4245 		break;
4246 	    ++lnum;
4247 	}
4248 
4249 	/* Find interesting text in this line. */
4250 	s = skipwhite(ml_get(lnum));
4251 	/* skip C comment-start */
4252 	if (s[0] == '/' && (s[1] == '*' || s[1] == '/'))
4253 	    s = skipwhite(s + 2);
4254 	txt = _("+-%s%3ld lines: ");
4255 	r = alloc((unsigned)(STRLEN(txt)
4256 		    + STRLEN(vimvars[VV_FOLDDASHES].val)    /* for %s */
4257 		    + 20				    /* for %3ld */
4258 		    + STRLEN(s)));			    /* concatenated */
4259 	if (r != NULL)
4260 	{
4261 	    sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].val,
4262 		    (long)((linenr_T)vimvars[VV_FOLDEND].val
4263 				   - (linenr_T)vimvars[VV_FOLDSTART].val + 1));
4264 	    len = (int)STRLEN(r);
4265 	    STRCAT(r, s);
4266 	    /* remove 'foldmarker' and 'commentstring' */
4267 	    foldtext_cleanup(r + len);
4268 	    retvar->var_val.var_string = r;
4269 	}
4270     }
4271 #endif
4272 }
4273 
4274 /*
4275  * "foreground()" function
4276  */
4277 /*ARGSUSED*/
4278     static void
4279 f_foreground(argvars, retvar)
4280     VAR		argvars;
4281     VAR		retvar;
4282 {
4283     retvar->var_val.var_number = 0;
4284 #ifdef FEAT_GUI
4285     if (gui.in_use)
4286 	gui_mch_set_foreground();
4287 #else
4288 # ifdef WIN32
4289     win32_set_foreground();
4290 # endif
4291 #endif
4292 }
4293 
4294 /*
4295  * "getchar()" function
4296  */
4297     static void
4298 f_getchar(argvars, retvar)
4299     VAR		argvars;
4300     VAR		retvar;
4301 {
4302     varnumber_T		n;
4303 
4304     ++no_mapping;
4305     ++allow_keys;
4306     if (argvars[0].var_type == VAR_UNKNOWN)
4307 	/* getchar(): blocking wait. */
4308 	n = safe_vgetc();
4309     else if (get_var_number(&argvars[0]) == 1)
4310 	/* getchar(1): only check if char avail */
4311 	n = vpeekc();
4312     else if (vpeekc() == NUL)
4313 	/* getchar(0) and no char avail: return zero */
4314 	n = 0;
4315     else
4316 	/* getchar(0) and char avail: return char */
4317 	n = safe_vgetc();
4318     --no_mapping;
4319     --allow_keys;
4320 
4321     retvar->var_val.var_number = n;
4322     if (IS_SPECIAL(n) || mod_mask != 0)
4323     {
4324 	char_u		temp[10];   /* modifier: 3, mbyte-char: 6, NUL: 1 */
4325 	int		i = 0;
4326 
4327 	/* Turn a special key into three bytes, plus modifier. */
4328 	if (mod_mask != 0)
4329 	{
4330 	    temp[i++] = K_SPECIAL;
4331 	    temp[i++] = KS_MODIFIER;
4332 	    temp[i++] = mod_mask;
4333 	}
4334 	if (IS_SPECIAL(n))
4335 	{
4336 	    temp[i++] = K_SPECIAL;
4337 	    temp[i++] = K_SECOND(n);
4338 	    temp[i++] = K_THIRD(n);
4339 	}
4340 #ifdef FEAT_MBYTE
4341 	else if (has_mbyte)
4342 	    i += (*mb_char2bytes)(n, temp + i);
4343 #endif
4344 	else
4345 	    temp[i++] = n;
4346 	temp[i++] = NUL;
4347 	retvar->var_type = VAR_STRING;
4348 	retvar->var_val.var_string = vim_strsave(temp);
4349     }
4350 }
4351 
4352 /*
4353  * "getcharmod()" function
4354  */
4355 /*ARGSUSED*/
4356     static void
4357 f_getcharmod(argvars, retvar)
4358     VAR		argvars;
4359     VAR		retvar;
4360 {
4361     retvar->var_val.var_number = mod_mask;
4362 }
4363 
4364 /*
4365  * "getcmdline()" function
4366  */
4367 /*ARGSUSED*/
4368     static void
4369 f_getcmdline(argvars, retvar)
4370     VAR		argvars;
4371     VAR		retvar;
4372 {
4373     retvar->var_type = VAR_STRING;
4374     retvar->var_val.var_string = get_cmdline_str();
4375 }
4376 
4377 /*
4378  * "getcmdpos()" function
4379  */
4380 /*ARGSUSED*/
4381     static void
4382 f_getcmdpos(argvars, retvar)
4383     VAR		argvars;
4384     VAR		retvar;
4385 {
4386     retvar->var_val.var_number = get_cmdline_pos() + 1;
4387 }
4388 
4389 /*
4390  * "getbufvar()" function
4391  */
4392     static void
4393 f_getbufvar(argvars, retvar)
4394     VAR		argvars;
4395     VAR		retvar;
4396 {
4397     buf_T	*buf;
4398     buf_T	*save_curbuf;
4399     char_u	*varname;
4400     VAR		v;
4401 
4402     ++emsg_off;
4403     buf = get_buf_var(&argvars[0]);
4404     varname = get_var_string(&argvars[1]);
4405 
4406     retvar->var_type = VAR_STRING;
4407     retvar->var_val.var_string = NULL;
4408 
4409     if (buf != NULL && varname != NULL)
4410     {
4411 	if (*varname == '&')	/* buffer-local-option */
4412 	{
4413 	    /* set curbuf to be our buf, temporarily */
4414 	    save_curbuf = curbuf;
4415 	    curbuf = buf;
4416 
4417 	    get_option_var(&varname, retvar, TRUE);
4418 
4419 	    /* restore previous notion of curbuf */
4420 	    curbuf = save_curbuf;
4421 	}
4422 	else
4423 	{
4424 	    /* look up the variable */
4425 	    v = find_var_in_ga(&buf->b_vars, varname);
4426 	    if (v != NULL)
4427 		copy_var(v, retvar);
4428 	}
4429     }
4430 
4431     --emsg_off;
4432 }
4433 
4434 /*
4435  * "getcwd()" function
4436  */
4437 /*ARGSUSED*/
4438     static void
4439 f_getcwd(argvars, retvar)
4440     VAR		argvars;
4441     VAR		retvar;
4442 {
4443     char_u	cwd[MAXPATHL];
4444 
4445     retvar->var_type = VAR_STRING;
4446     if (mch_dirname(cwd, MAXPATHL) == FAIL)
4447 	retvar->var_val.var_string = NULL;
4448     else
4449     {
4450 	retvar->var_val.var_string = vim_strsave(cwd);
4451 #ifdef BACKSLASH_IN_FILENAME
4452 	slash_adjust(retvar->var_val.var_string);
4453 #endif
4454     }
4455 }
4456 
4457 /*
4458  * "getfsize({fname})" function
4459  */
4460     static void
4461 f_getfsize(argvars, retvar)
4462     VAR		argvars;
4463     VAR		retvar;
4464 {
4465     char_u	*fname;
4466     struct stat	st;
4467 
4468     fname = get_var_string(&argvars[0]);
4469 
4470     retvar->var_type = VAR_NUMBER;
4471 
4472     if (mch_stat((char *)fname, &st) >= 0)
4473     {
4474 	if (mch_isdir(fname))
4475 	    retvar->var_val.var_number = 0;
4476 	else
4477 	    retvar->var_val.var_number = (varnumber_T)st.st_size;
4478     }
4479     else
4480 	  retvar->var_val.var_number = -1;
4481 }
4482 
4483 /*
4484  * "getftime({fname})" function
4485  */
4486     static void
4487 f_getftime(argvars, retvar)
4488     VAR		argvars;
4489     VAR		retvar;
4490 {
4491     char_u	*fname;
4492     struct stat	st;
4493 
4494     fname = get_var_string(&argvars[0]);
4495 
4496     if (mch_stat((char *)fname, &st) >= 0)
4497 	retvar->var_val.var_number = (varnumber_T)st.st_mtime;
4498     else
4499 	retvar->var_val.var_number = -1;
4500 }
4501 
4502 /*
4503  * "getreg()" function
4504  */
4505     static void
4506 f_getreg(argvars, retvar)
4507     VAR		argvars;
4508     VAR		retvar;
4509 {
4510     char_u	*strregname;
4511     int		regname;
4512 
4513     if (argvars[0].var_type != VAR_UNKNOWN)
4514 	strregname = get_var_string(&argvars[0]);
4515     else
4516 	strregname = vimvars[VV_REG].val;
4517     regname = (strregname == NULL ? '"' : *strregname);
4518     if (regname == 0)
4519 	regname = '"';
4520 
4521     retvar->var_type = VAR_STRING;
4522     retvar->var_val.var_string = get_reg_contents(regname, TRUE);
4523 }
4524 
4525 /*
4526  * "getregtype()" function
4527  */
4528     static void
4529 f_getregtype(argvars, retvar)
4530     VAR		argvars;
4531     VAR		retvar;
4532 {
4533     char_u	*strregname;
4534     int		regname;
4535     char_u	buf[NUMBUFLEN + 2];
4536     long	reglen = 0;
4537 
4538     if (argvars[0].var_type != VAR_UNKNOWN)
4539 	strregname = get_var_string(&argvars[0]);
4540     else
4541 	/* Default to v:register */
4542 	strregname = vimvars[VV_REG].val;
4543 
4544     regname = (strregname == NULL ? '"' : *strregname);
4545     if (regname == 0)
4546 	regname = '"';
4547 
4548     buf[0] = NUL;
4549     buf[1] = NUL;
4550     switch (get_reg_type(regname, &reglen))
4551     {
4552 	case MLINE: buf[0] = 'V'; break;
4553 	case MCHAR: buf[0] = 'v'; break;
4554 #ifdef FEAT_VISUAL
4555 	case MBLOCK:
4556 		buf[0] = Ctrl_V;
4557 		sprintf((char *)buf + 1, "%ld", reglen + 1);
4558 		break;
4559 #endif
4560     }
4561     retvar->var_type = VAR_STRING;
4562     retvar->var_val.var_string = vim_strsave(buf);
4563 }
4564 
4565 /*
4566  * "getline(lnum)" function
4567  */
4568     static void
4569 f_getline(argvars, retvar)
4570     VAR		argvars;
4571     VAR		retvar;
4572 {
4573     linenr_T	lnum;
4574     char_u	*p;
4575 
4576     lnum = get_var_lnum(argvars);
4577 
4578     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
4579 	p = ml_get(lnum);
4580     else
4581 	p = (char_u *)"";
4582 
4583     retvar->var_type = VAR_STRING;
4584     retvar->var_val.var_string = vim_strsave(p);
4585 }
4586 
4587 /*
4588  * "getwinposx()" function
4589  */
4590 /*ARGSUSED*/
4591     static void
4592 f_getwinposx(argvars, retvar)
4593     VAR		argvars;
4594     VAR		retvar;
4595 {
4596     retvar->var_val.var_number = -1;
4597 #ifdef FEAT_GUI
4598     if (gui.in_use)
4599     {
4600 	int	    x, y;
4601 
4602 	if (gui_mch_get_winpos(&x, &y) == OK)
4603 	    retvar->var_val.var_number = x;
4604     }
4605 #endif
4606 }
4607 
4608 /*
4609  * "getwinposy()" function
4610  */
4611 /*ARGSUSED*/
4612     static void
4613 f_getwinposy(argvars, retvar)
4614     VAR		argvars;
4615     VAR		retvar;
4616 {
4617     retvar->var_val.var_number = -1;
4618 #ifdef FEAT_GUI
4619     if (gui.in_use)
4620     {
4621 	int	    x, y;
4622 
4623 	if (gui_mch_get_winpos(&x, &y) == OK)
4624 	    retvar->var_val.var_number = y;
4625     }
4626 #endif
4627 }
4628 
4629 /*
4630  * "getwinvar()" function
4631  */
4632     static void
4633 f_getwinvar(argvars, retvar)
4634     VAR		argvars;
4635     VAR		retvar;
4636 {
4637     win_T	*win, *oldcurwin;
4638     char_u	*varname;
4639     VAR		v;
4640 
4641     ++emsg_off;
4642     win = find_win_by_nr(&argvars[0]);
4643     varname = get_var_string(&argvars[1]);
4644 
4645     retvar->var_type = VAR_STRING;
4646     retvar->var_val.var_string = NULL;
4647 
4648     if (win != NULL && varname != NULL)
4649     {
4650 	if (*varname == '&')	/* window-local-option */
4651 	{
4652 	    /* set curwin to be our win, temporarily */
4653 	    oldcurwin = curwin;
4654 	    curwin = win;
4655 
4656 	    get_option_var(&varname, retvar , 1);
4657 
4658 	    /* restore previous notion of curwin */
4659 	    curwin = oldcurwin;
4660 	}
4661 	else
4662 	{
4663 	    /* look up the variable */
4664 	    v = find_var_in_ga(&win->w_vars, varname);
4665 	    if (v != NULL)
4666 		copy_var(v, retvar);
4667 	}
4668     }
4669 
4670     --emsg_off;
4671 }
4672 
4673 /*
4674  * "glob()" function
4675  */
4676     static void
4677 f_glob(argvars, retvar)
4678     VAR		argvars;
4679     VAR		retvar;
4680 {
4681     expand_T	xpc;
4682 
4683     ExpandInit(&xpc);
4684     xpc.xp_context = EXPAND_FILES;
4685     retvar->var_type = VAR_STRING;
4686     retvar->var_val.var_string = ExpandOne(&xpc, get_var_string(&argvars[0]),
4687 				     NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL);
4688     ExpandCleanup(&xpc);
4689 }
4690 
4691 /*
4692  * "globpath()" function
4693  */
4694     static void
4695 f_globpath(argvars, retvar)
4696     VAR		argvars;
4697     VAR		retvar;
4698 {
4699     char_u	buf1[NUMBUFLEN];
4700 
4701     retvar->var_type = VAR_STRING;
4702     retvar->var_val.var_string = globpath(get_var_string(&argvars[0]),
4703 				       get_var_string_buf(&argvars[1], buf1));
4704 }
4705 
4706 /*
4707  * "has()" function
4708  */
4709     static void
4710 f_has(argvars, retvar)
4711     VAR		argvars;
4712     VAR		retvar;
4713 {
4714     int		i;
4715     char_u	*name;
4716     int		n = FALSE;
4717     static char	*(has_list[]) =
4718     {
4719 #ifdef AMIGA
4720 	"amiga",
4721 # ifdef FEAT_ARP
4722 	"arp",
4723 # endif
4724 #endif
4725 #ifdef __BEOS__
4726 	"beos",
4727 #endif
4728 #ifdef MSDOS
4729 # ifdef DJGPP
4730 	"dos32",
4731 # else
4732 	"dos16",
4733 # endif
4734 #endif
4735 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */
4736 	"mac",
4737 #endif
4738 #if defined(MACOS_X_UNIX)
4739 	"macunix",
4740 #endif
4741 #ifdef OS2
4742 	"os2",
4743 #endif
4744 #ifdef __QNX__
4745 	"qnx",
4746 #endif
4747 #ifdef RISCOS
4748 	"riscos",
4749 #endif
4750 #ifdef UNIX
4751 	"unix",
4752 #endif
4753 #ifdef VMS
4754 	"vms",
4755 #endif
4756 #ifdef WIN16
4757 	"win16",
4758 #endif
4759 #ifdef WIN32
4760 	"win32",
4761 #endif
4762 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__))
4763 	"win32unix",
4764 #endif
4765 #ifdef WIN64
4766 	"win64",
4767 #endif
4768 #ifdef EBCDIC
4769 	"ebcdic",
4770 #endif
4771 #ifndef CASE_INSENSITIVE_FILENAME
4772 	"fname_case",
4773 #endif
4774 #ifdef FEAT_ARABIC
4775 	"arabic",
4776 #endif
4777 #ifdef FEAT_AUTOCMD
4778 	"autocmd",
4779 #endif
4780 #ifdef FEAT_BEVAL
4781 	"balloon_eval",
4782 #endif
4783 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
4784 	"builtin_terms",
4785 # ifdef ALL_BUILTIN_TCAPS
4786 	"all_builtin_terms",
4787 # endif
4788 #endif
4789 #ifdef FEAT_BYTEOFF
4790 	"byte_offset",
4791 #endif
4792 #ifdef FEAT_CINDENT
4793 	"cindent",
4794 #endif
4795 #ifdef FEAT_CLIENTSERVER
4796 	"clientserver",
4797 #endif
4798 #ifdef FEAT_CLIPBOARD
4799 	"clipboard",
4800 #endif
4801 #ifdef FEAT_CMDL_COMPL
4802 	"cmdline_compl",
4803 #endif
4804 #ifdef FEAT_CMDHIST
4805 	"cmdline_hist",
4806 #endif
4807 #ifdef FEAT_COMMENTS
4808 	"comments",
4809 #endif
4810 #ifdef FEAT_CRYPT
4811 	"cryptv",
4812 #endif
4813 #ifdef FEAT_CSCOPE
4814 	"cscope",
4815 #endif
4816 #ifdef DEBUG
4817 	"debug",
4818 #endif
4819 #ifdef FEAT_CON_DIALOG
4820 	"dialog_con",
4821 #endif
4822 #ifdef FEAT_GUI_DIALOG
4823 	"dialog_gui",
4824 #endif
4825 #ifdef FEAT_DIFF
4826 	"diff",
4827 #endif
4828 #ifdef FEAT_DIGRAPHS
4829 	"digraphs",
4830 #endif
4831 #ifdef FEAT_DND
4832 	"dnd",
4833 #endif
4834 #ifdef FEAT_EMACS_TAGS
4835 	"emacs_tags",
4836 #endif
4837 	"eval",	    /* always present, of course! */
4838 #ifdef FEAT_EX_EXTRA
4839 	"ex_extra",
4840 #endif
4841 #ifdef FEAT_SEARCH_EXTRA
4842 	"extra_search",
4843 #endif
4844 #ifdef FEAT_FKMAP
4845 	"farsi",
4846 #endif
4847 #ifdef FEAT_SEARCHPATH
4848 	"file_in_path",
4849 #endif
4850 #ifdef FEAT_FIND_ID
4851 	"find_in_path",
4852 #endif
4853 #ifdef FEAT_FOLDING
4854 	"folding",
4855 #endif
4856 #ifdef FEAT_FOOTER
4857 	"footer",
4858 #endif
4859 #if !defined(USE_SYSTEM) && defined(UNIX)
4860 	"fork",
4861 #endif
4862 #ifdef FEAT_GETTEXT
4863 	"gettext",
4864 #endif
4865 #ifdef FEAT_GUI
4866 	"gui",
4867 #endif
4868 #ifdef FEAT_GUI_ATHENA
4869 # ifdef FEAT_GUI_NEXTAW
4870 	"gui_neXtaw",
4871 # else
4872 	"gui_athena",
4873 # endif
4874 #endif
4875 #ifdef FEAT_GUI_BEOS
4876 	"gui_beos",
4877 #endif
4878 #ifdef FEAT_GUI_GTK
4879 	"gui_gtk",
4880 # ifdef HAVE_GTK2
4881 	"gui_gtk2",
4882 # endif
4883 #endif
4884 #ifdef FEAT_GUI_MAC
4885 	"gui_mac",
4886 #endif
4887 #ifdef FEAT_GUI_MOTIF
4888 	"gui_motif",
4889 #endif
4890 #ifdef FEAT_GUI_PHOTON
4891 	"gui_photon",
4892 #endif
4893 #ifdef FEAT_GUI_W16
4894 	"gui_win16",
4895 #endif
4896 #ifdef FEAT_GUI_W32
4897 	"gui_win32",
4898 #endif
4899 #ifdef FEAT_HANGULIN
4900 	"hangul_input",
4901 #endif
4902 #if defined(HAVE_ICONV_H) && defined(USE_ICONV)
4903 	"iconv",
4904 #endif
4905 #ifdef FEAT_INS_EXPAND
4906 	"insert_expand",
4907 #endif
4908 #ifdef FEAT_JUMPLIST
4909 	"jumplist",
4910 #endif
4911 #ifdef FEAT_KEYMAP
4912 	"keymap",
4913 #endif
4914 #ifdef FEAT_LANGMAP
4915 	"langmap",
4916 #endif
4917 #ifdef FEAT_LIBCALL
4918 	"libcall",
4919 #endif
4920 #ifdef FEAT_LINEBREAK
4921 	"linebreak",
4922 #endif
4923 #ifdef FEAT_LISP
4924 	"lispindent",
4925 #endif
4926 #ifdef FEAT_LISTCMDS
4927 	"listcmds",
4928 #endif
4929 #ifdef FEAT_LOCALMAP
4930 	"localmap",
4931 #endif
4932 #ifdef FEAT_MENU
4933 	"menu",
4934 #endif
4935 #ifdef FEAT_SESSION
4936 	"mksession",
4937 #endif
4938 #ifdef FEAT_MODIFY_FNAME
4939 	"modify_fname",
4940 #endif
4941 #ifdef FEAT_MOUSE
4942 	"mouse",
4943 #endif
4944 #ifdef FEAT_MOUSESHAPE
4945 	"mouseshape",
4946 #endif
4947 #if defined(UNIX) || defined(VMS)
4948 # ifdef FEAT_MOUSE_DEC
4949 	"mouse_dec",
4950 # endif
4951 # ifdef FEAT_MOUSE_GPM
4952 	"mouse_gpm",
4953 # endif
4954 # ifdef FEAT_MOUSE_JSB
4955 	"mouse_jsbterm",
4956 # endif
4957 # ifdef FEAT_MOUSE_NET
4958 	"mouse_netterm",
4959 # endif
4960 # ifdef FEAT_MOUSE_PTERM
4961 	"mouse_pterm",
4962 # endif
4963 # ifdef FEAT_MOUSE_XTERM
4964 	"mouse_xterm",
4965 # endif
4966 #endif
4967 #ifdef FEAT_MBYTE
4968 	"multi_byte",
4969 #endif
4970 #ifdef FEAT_MBYTE_IME
4971 	"multi_byte_ime",
4972 #endif
4973 #ifdef FEAT_MULTI_LANG
4974 	"multi_lang",
4975 #endif
4976 #ifdef FEAT_OLE
4977 	"ole",
4978 #endif
4979 #ifdef FEAT_OSFILETYPE
4980 	"osfiletype",
4981 #endif
4982 #ifdef FEAT_PATH_EXTRA
4983 	"path_extra",
4984 #endif
4985 #ifdef FEAT_PERL
4986 #ifndef DYNAMIC_PERL
4987 	"perl",
4988 #endif
4989 #endif
4990 #ifdef FEAT_PYTHON
4991 #ifndef DYNAMIC_PYTHON
4992 	"python",
4993 #endif
4994 #endif
4995 #ifdef FEAT_POSTSCRIPT
4996 	"postscript",
4997 #endif
4998 #ifdef FEAT_PRINTER
4999 	"printer",
5000 #endif
5001 #ifdef FEAT_QUICKFIX
5002 	"quickfix",
5003 #endif
5004 #ifdef FEAT_RIGHTLEFT
5005 	"rightleft",
5006 #endif
5007 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY)
5008 	"ruby",
5009 #endif
5010 #ifdef FEAT_SCROLLBIND
5011 	"scrollbind",
5012 #endif
5013 #ifdef FEAT_CMDL_INFO
5014 	"showcmd",
5015 	"cmdline_info",
5016 #endif
5017 #ifdef FEAT_SIGNS
5018 	"signs",
5019 #endif
5020 #ifdef FEAT_SMARTINDENT
5021 	"smartindent",
5022 #endif
5023 #ifdef FEAT_SNIFF
5024 	"sniff",
5025 #endif
5026 #ifdef FEAT_STL_OPT
5027 	"statusline",
5028 #endif
5029 #ifdef FEAT_SUN_WORKSHOP
5030 	"sun_workshop",
5031 #endif
5032 #ifdef FEAT_NETBEANS_INTG
5033 	"netbeans_intg",
5034 #endif
5035 #ifdef FEAT_SYN_HL
5036 	"syntax",
5037 #endif
5038 #if defined(USE_SYSTEM) || !defined(UNIX)
5039 	"system",
5040 #endif
5041 #ifdef FEAT_TAG_BINS
5042 	"tag_binary",
5043 #endif
5044 #ifdef FEAT_TAG_OLDSTATIC
5045 	"tag_old_static",
5046 #endif
5047 #ifdef FEAT_TAG_ANYWHITE
5048 	"tag_any_white",
5049 #endif
5050 #ifdef FEAT_TCL
5051 # ifndef DYNAMIC_TCL
5052 	"tcl",
5053 # endif
5054 #endif
5055 #ifdef TERMINFO
5056 	"terminfo",
5057 #endif
5058 #ifdef FEAT_TERMRESPONSE
5059 	"termresponse",
5060 #endif
5061 #ifdef FEAT_TEXTOBJ
5062 	"textobjects",
5063 #endif
5064 #ifdef HAVE_TGETENT
5065 	"tgetent",
5066 #endif
5067 #ifdef FEAT_TITLE
5068 	"title",
5069 #endif
5070 #ifdef FEAT_TOOLBAR
5071 	"toolbar",
5072 #endif
5073 #ifdef FEAT_USR_CMDS
5074 	"user-commands",    /* was accidentally included in 5.4 */
5075 	"user_commands",
5076 #endif
5077 #ifdef FEAT_VIMINFO
5078 	"viminfo",
5079 #endif
5080 #ifdef FEAT_VERTSPLIT
5081 	"vertsplit",
5082 #endif
5083 #ifdef FEAT_VIRTUALEDIT
5084 	"virtualedit",
5085 #endif
5086 #ifdef FEAT_VISUAL
5087 	"visual",
5088 #endif
5089 #ifdef FEAT_VISUALEXTRA
5090 	"visualextra",
5091 #endif
5092 #ifdef FEAT_VREPLACE
5093 	"vreplace",
5094 #endif
5095 #ifdef FEAT_WILDIGN
5096 	"wildignore",
5097 #endif
5098 #ifdef FEAT_WILDMENU
5099 	"wildmenu",
5100 #endif
5101 #ifdef FEAT_WINDOWS
5102 	"windows",
5103 #endif
5104 #ifdef FEAT_WAK
5105 	"winaltkeys",
5106 #endif
5107 #ifdef FEAT_WRITEBACKUP
5108 	"writebackup",
5109 #endif
5110 #ifdef FEAT_XIM
5111 	"xim",
5112 #endif
5113 #ifdef FEAT_XFONTSET
5114 	"xfontset",
5115 #endif
5116 #ifdef USE_XSMP
5117 	"xsmp",
5118 #endif
5119 #ifdef USE_XSMP_INTERACT
5120 	"xsmp_interact",
5121 #endif
5122 #ifdef FEAT_XCLIPBOARD
5123 	"xterm_clipboard",
5124 #endif
5125 #ifdef FEAT_XTERM_SAVE
5126 	"xterm_save",
5127 #endif
5128 #if defined(UNIX) && defined(FEAT_X11)
5129 	"X11",
5130 #endif
5131 	NULL
5132     };
5133 
5134     name = get_var_string(&argvars[0]);
5135     for (i = 0; has_list[i] != NULL; ++i)
5136 	if (STRICMP(name, has_list[i]) == 0)
5137 	{
5138 	    n = TRUE;
5139 	    break;
5140 	}
5141 
5142     if (n == FALSE)
5143     {
5144 	if (STRNICMP(name, "patch", 5) == 0)
5145 	    n = has_patch(atoi((char *)name + 5));
5146 	else if (STRICMP(name, "vim_starting") == 0)
5147 	    n = (starting != 0);
5148 #ifdef DYNAMIC_TCL
5149 	else if (STRICMP(name, "tcl") == 0)
5150 	    n = tcl_enabled(FALSE);
5151 #endif
5152 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
5153 	else if (STRICMP(name, "iconv") == 0)
5154 	    n = iconv_enabled(FALSE);
5155 #endif
5156 #ifdef DYNAMIC_RUBY
5157 	else if (STRICMP(name, "ruby") == 0)
5158 	    n = ruby_enabled(FALSE);
5159 #endif
5160 #ifdef DYNAMIC_PYTHON
5161 	else if (STRICMP(name, "python") == 0)
5162 	    n = python_enabled(FALSE);
5163 #endif
5164 #ifdef DYNAMIC_PERL
5165 	else if (STRICMP(name, "perl") == 0)
5166 	    n = perl_enabled(FALSE);
5167 #endif
5168 #ifdef FEAT_GUI
5169 	else if (STRICMP(name, "gui_running") == 0)
5170 	    n = (gui.in_use || gui.starting);
5171 # ifdef FEAT_GUI_W32
5172 	else if (STRICMP(name, "gui_win32s") == 0)
5173 	    n = gui_is_win32s();
5174 # endif
5175 # ifdef FEAT_BROWSE
5176 	else if (STRICMP(name, "browse") == 0)
5177 	    n = gui.in_use;	/* gui_mch_browse() works when GUI is running */
5178 # endif
5179 #endif
5180 #ifdef FEAT_SYN_HL
5181 	else if (STRICMP(name, "syntax_items") == 0)
5182 	    n = syntax_present(curbuf);
5183 #endif
5184 #if defined(WIN3264)
5185 	else if (STRICMP(name, "win95") == 0)
5186 	    n = mch_windows95();
5187 #endif
5188     }
5189 
5190     retvar->var_val.var_number = n;
5191 }
5192 
5193 /*
5194  * "hasmapto()" function
5195  */
5196     static void
5197 f_hasmapto(argvars, retvar)
5198     VAR		argvars;
5199     VAR		retvar;
5200 {
5201     char_u	*name;
5202     char_u	*mode;
5203     char_u	buf[NUMBUFLEN];
5204 
5205     name = get_var_string(&argvars[0]);
5206     if (argvars[1].var_type == VAR_UNKNOWN)
5207 	mode = (char_u *)"nvo";
5208     else
5209 	mode = get_var_string_buf(&argvars[1], buf);
5210 
5211     if (map_to_exists(name, mode))
5212 	retvar->var_val.var_number = TRUE;
5213     else
5214 	retvar->var_val.var_number = FALSE;
5215 }
5216 
5217 /*
5218  * "histadd()" function
5219  */
5220 /*ARGSUSED*/
5221     static void
5222 f_histadd(argvars, retvar)
5223     VAR		argvars;
5224     VAR		retvar;
5225 {
5226 #ifdef FEAT_CMDHIST
5227     int		histype;
5228     char_u	*str;
5229     char_u	buf[NUMBUFLEN];
5230 #endif
5231 
5232     retvar->var_val.var_number = FALSE;
5233     if (check_restricted() || check_secure())
5234 	return;
5235 #ifdef FEAT_CMDHIST
5236     histype = get_histtype(get_var_string(&argvars[0]));
5237     if (histype >= 0)
5238     {
5239 	str = get_var_string_buf(&argvars[1], buf);
5240 	if (*str != NUL)
5241 	{
5242 	    add_to_history(histype, str, FALSE, NUL);
5243 	    retvar->var_val.var_number = TRUE;
5244 	    return;
5245 	}
5246     }
5247 #endif
5248 }
5249 
5250 /*
5251  * "histdel()" function
5252  */
5253 /*ARGSUSED*/
5254     static void
5255 f_histdel(argvars, retvar)
5256     VAR		argvars;
5257     VAR		retvar;
5258 {
5259 #ifdef FEAT_CMDHIST
5260     int		n;
5261     char_u	buf[NUMBUFLEN];
5262 
5263     if (argvars[1].var_type == VAR_UNKNOWN)
5264 	/* only one argument: clear entire history */
5265 	n = clr_history(get_histtype(get_var_string(&argvars[0])));
5266     else if (argvars[1].var_type == VAR_NUMBER)
5267 	/* index given: remove that entry */
5268 	n = del_history_idx(get_histtype(get_var_string(&argvars[0])),
5269 					    (int)get_var_number(&argvars[1]));
5270     else
5271 	/* string given: remove all matching entries */
5272 	n = del_history_entry(get_histtype(get_var_string(&argvars[0])),
5273 					get_var_string_buf(&argvars[1], buf));
5274     retvar->var_val.var_number = n;
5275 #else
5276     retvar->var_val.var_number = 0;
5277 #endif
5278 }
5279 
5280 /*
5281  * "histget()" function
5282  */
5283 /*ARGSUSED*/
5284     static void
5285 f_histget(argvars, retvar)
5286     VAR		argvars;
5287     VAR		retvar;
5288 {
5289 #ifdef FEAT_CMDHIST
5290     int		type;
5291     int		idx;
5292 
5293     type = get_histtype(get_var_string(&argvars[0]));
5294     if (argvars[1].var_type == VAR_UNKNOWN)
5295 	idx = get_history_idx(type);
5296     else
5297 	idx = (int)get_var_number(&argvars[1]);
5298     retvar->var_val.var_string = vim_strsave(get_history_entry(type, idx));
5299 #else
5300     retvar->var_val.var_string = NULL;
5301 #endif
5302     retvar->var_type = VAR_STRING;
5303 }
5304 
5305 /*
5306  * "histnr()" function
5307  */
5308 /*ARGSUSED*/
5309     static void
5310 f_histnr(argvars, retvar)
5311     VAR		argvars;
5312     VAR		retvar;
5313 {
5314     int		i;
5315 
5316 #ifdef FEAT_CMDHIST
5317     i = get_histtype(get_var_string(&argvars[0]));
5318     if (i >= HIST_CMD && i < HIST_COUNT)
5319 	i = get_history_idx(i);
5320     else
5321 #endif
5322 	i = -1;
5323     retvar->var_val.var_number = i;
5324 }
5325 
5326 /*
5327  * "highlight_exists()" function
5328  */
5329     static void
5330 f_hlexists(argvars, retvar)
5331     VAR		argvars;
5332     VAR		retvar;
5333 {
5334     retvar->var_val.var_number = highlight_exists(get_var_string(&argvars[0]));
5335 }
5336 
5337 /*
5338  * "highlightID(name)" function
5339  */
5340     static void
5341 f_hlID(argvars, retvar)
5342     VAR		argvars;
5343     VAR		retvar;
5344 {
5345     retvar->var_val.var_number = syn_name2id(get_var_string(&argvars[0]));
5346 }
5347 
5348 /*
5349  * "hostname()" function
5350  */
5351 /*ARGSUSED*/
5352     static void
5353 f_hostname(argvars, retvar)
5354     VAR		argvars;
5355     VAR		retvar;
5356 {
5357     char_u hostname[256];
5358 
5359     mch_get_host_name(hostname, 256);
5360     retvar->var_type = VAR_STRING;
5361     retvar->var_val.var_string = vim_strsave(hostname);
5362 }
5363 
5364 /*
5365  * iconv() function
5366  */
5367 /*ARGSUSED*/
5368     static void
5369 f_iconv(argvars, retvar)
5370     VAR		argvars;
5371     VAR		retvar;
5372 {
5373 #ifdef FEAT_MBYTE
5374     char_u	buf1[NUMBUFLEN];
5375     char_u	buf2[NUMBUFLEN];
5376     char_u	*from, *to, *str;
5377     vimconv_T	vimconv;
5378 #endif
5379 
5380     retvar->var_type = VAR_STRING;
5381     retvar->var_val.var_string = NULL;
5382 
5383 #ifdef FEAT_MBYTE
5384     str = get_var_string(&argvars[0]);
5385     from = enc_canonize(enc_skip(get_var_string_buf(&argvars[1], buf1)));
5386     to = enc_canonize(enc_skip(get_var_string_buf(&argvars[2], buf2)));
5387     vimconv.vc_type = CONV_NONE;
5388     convert_setup(&vimconv, from, to);
5389 
5390     /* If the encodings are equal, no conversion needed. */
5391     if (vimconv.vc_type == CONV_NONE)
5392 	retvar->var_val.var_string = vim_strsave(str);
5393     else
5394 	retvar->var_val.var_string = string_convert(&vimconv, str, NULL);
5395 
5396     convert_setup(&vimconv, NULL, NULL);
5397     vim_free(from);
5398     vim_free(to);
5399 #endif
5400 }
5401 
5402 /*
5403  * "indent()" function
5404  */
5405     static void
5406 f_indent(argvars, retvar)
5407     VAR		argvars;
5408     VAR		retvar;
5409 {
5410     linenr_T	lnum;
5411 
5412     lnum = get_var_lnum(argvars);
5413     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
5414 	retvar->var_val.var_number = get_indent_lnum(lnum);
5415     else
5416 	retvar->var_val.var_number = -1;
5417 }
5418 
5419 static int inputsecret_flag = 0;
5420 
5421 /*
5422  * "input()" function
5423  *     Also handles inputsecret() when inputsecret is set.
5424  */
5425     static void
5426 f_input(argvars, retvar)
5427     VAR		argvars;
5428     VAR		retvar;
5429 {
5430     char_u	*prompt = get_var_string(&argvars[0]);
5431     char_u	*p = NULL;
5432     int		c;
5433     char_u	buf[NUMBUFLEN];
5434     int		cmd_silent_save = cmd_silent;
5435 
5436     retvar->var_type = VAR_STRING;
5437 
5438 #ifdef NO_CONSOLE_INPUT
5439     /* While starting up, there is no place to enter text. */
5440     if (no_console_input())
5441     {
5442 	retvar->var_val.var_string = NULL;
5443 	return;
5444     }
5445 #endif
5446 
5447     cmd_silent = FALSE;		/* Want to see the prompt. */
5448     if (prompt != NULL)
5449     {
5450 	/* Only the part of the message after the last NL is considered as
5451 	 * prompt for the command line */
5452 	p = vim_strrchr(prompt, '\n');
5453 	if (p == NULL)
5454 	    p = prompt;
5455 	else
5456 	{
5457 	    ++p;
5458 	    c = *p;
5459 	    *p = NUL;
5460 	    msg_start();
5461 	    msg_clr_eos();
5462 	    msg_puts_attr(prompt, echo_attr);
5463 	    msg_didout = FALSE;
5464 	    msg_starthere();
5465 	    *p = c;
5466 	}
5467 	cmdline_row = msg_row;
5468     }
5469 
5470     if (argvars[1].var_type != VAR_UNKNOWN)
5471 	stuffReadbuffSpec(get_var_string_buf(&argvars[1], buf));
5472 
5473     retvar->var_val.var_string =
5474 		getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr);
5475 
5476     /* since the user typed this, no need to wait for return */
5477     need_wait_return = FALSE;
5478     msg_didout = FALSE;
5479     cmd_silent = cmd_silent_save;
5480 }
5481 
5482 /*
5483  * "inputdialog()" function
5484  */
5485     static void
5486 f_inputdialog(argvars, retvar)
5487     VAR		argvars;
5488     VAR		retvar;
5489 {
5490 #if defined(FEAT_GUI_TEXTDIALOG)
5491     /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */
5492     if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL)
5493     {
5494 	char_u	*message;
5495 	char_u	buf[NUMBUFLEN];
5496 
5497 	message = get_var_string(&argvars[0]);
5498 	if (argvars[1].var_type != VAR_UNKNOWN)
5499 	{
5500 	    STRNCPY(IObuff, get_var_string_buf(&argvars[1], buf), IOSIZE);
5501 	    IObuff[IOSIZE - 1] = NUL;
5502 	}
5503 	else
5504 	    IObuff[0] = NUL;
5505 	if (do_dialog(VIM_QUESTION, NULL, message, (char_u *)_("&OK\n&Cancel"),
5506 							      1, IObuff) == 1)
5507 	    retvar->var_val.var_string = vim_strsave(IObuff);
5508 	else
5509 	{
5510 	    if (argvars[1].var_type != VAR_UNKNOWN
5511 					&& argvars[2].var_type != VAR_UNKNOWN)
5512 		retvar->var_val.var_string = vim_strsave(
5513 					get_var_string_buf(&argvars[2], buf));
5514 	    else
5515 		retvar->var_val.var_string = NULL;
5516 	}
5517 	retvar->var_type = VAR_STRING;
5518     }
5519     else
5520 #endif
5521 	f_input(argvars, retvar);
5522 }
5523 
5524 static garray_T	    ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL};
5525 
5526 /*
5527  * "inputrestore()" function
5528  */
5529 /*ARGSUSED*/
5530     static void
5531 f_inputrestore(argvars, retvar)
5532     VAR		argvars;
5533     VAR		retvar;
5534 {
5535     if (ga_userinput.ga_len > 0)
5536     {
5537 	--ga_userinput.ga_len;
5538 	++ga_userinput.ga_room;
5539 	restore_typeahead((tasave_T *)(ga_userinput.ga_data)
5540 						       + ga_userinput.ga_len);
5541 	retvar->var_val.var_number = 0; /* OK */
5542     }
5543     else if (p_verbose > 1)
5544     {
5545 	msg((char_u *)_("called inputrestore() more often than inputsave()"));
5546 	retvar->var_val.var_number = 1; /* Failed */
5547     }
5548 }
5549 
5550 /*
5551  * "inputsave()" function
5552  */
5553 /*ARGSUSED*/
5554     static void
5555 f_inputsave(argvars, retvar)
5556     VAR		argvars;
5557     VAR		retvar;
5558 {
5559     /* Add an entry to the stack of typehead storage. */
5560     if (ga_grow(&ga_userinput, 1) == OK)
5561     {
5562 	save_typeahead((tasave_T *)(ga_userinput.ga_data)
5563 						       + ga_userinput.ga_len);
5564 	++ga_userinput.ga_len;
5565 	--ga_userinput.ga_room;
5566 	retvar->var_val.var_number = 0; /* OK */
5567     }
5568     else
5569 	retvar->var_val.var_number = 1; /* Failed */
5570 }
5571 
5572 /*
5573  * "inputsecret()" function
5574  */
5575     static void
5576 f_inputsecret(argvars, retvar)
5577     VAR		argvars;
5578     VAR		retvar;
5579 {
5580     ++cmdline_star;
5581     ++inputsecret_flag;
5582     f_input(argvars, retvar);
5583     --cmdline_star;
5584     --inputsecret_flag;
5585 }
5586 
5587 /*
5588  * "isdirectory()" function
5589  */
5590     static void
5591 f_isdirectory(argvars, retvar)
5592     VAR		argvars;
5593     VAR		retvar;
5594 {
5595     retvar->var_val.var_number = mch_isdir(get_var_string(&argvars[0]));
5596 }
5597 
5598 /*
5599  * "last_buffer_nr()" function.
5600  */
5601 /*ARGSUSED*/
5602     static void
5603 f_last_buffer_nr(argvars, retvar)
5604     VAR		argvars;
5605     VAR		retvar;
5606 {
5607     int		n = 0;
5608     buf_T	*buf;
5609 
5610     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
5611 	if (n < buf->b_fnum)
5612 	    n = buf->b_fnum;
5613 
5614     retvar->var_val.var_number = n;
5615 }
5616 
5617 /*
5618  * "line(string)" function
5619  */
5620     static void
5621 f_line(argvars, retvar)
5622     VAR		argvars;
5623     VAR		retvar;
5624 {
5625     linenr_T	lnum = 0;
5626     pos_T	*fp;
5627 
5628     fp = var2fpos(&argvars[0], TRUE);
5629     if (fp != NULL)
5630 	lnum = fp->lnum;
5631     retvar->var_val.var_number = lnum;
5632 }
5633 
5634 /*
5635  * "line2byte(lnum)" function
5636  */
5637 /*ARGSUSED*/
5638     static void
5639 f_line2byte(argvars, retvar)
5640     VAR		argvars;
5641     VAR		retvar;
5642 {
5643 #ifndef FEAT_BYTEOFF
5644     retvar->var_val.var_number = -1;
5645 #else
5646     linenr_T	lnum;
5647 
5648     lnum = get_var_lnum(argvars);
5649     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
5650 	retvar->var_val.var_number = -1;
5651     else
5652 	retvar->var_val.var_number = ml_find_line_or_offset(curbuf, lnum, NULL);
5653     if (retvar->var_val.var_number >= 0)
5654 	++retvar->var_val.var_number;
5655 #endif
5656 }
5657 
5658 /*
5659  * "lispindent(lnum)" function
5660  */
5661     static void
5662 f_lispindent(argvars, retvar)
5663     VAR		argvars;
5664     VAR		retvar;
5665 {
5666 #ifdef FEAT_LISP
5667     pos_T	pos;
5668     linenr_T	lnum;
5669 
5670     pos = curwin->w_cursor;
5671     lnum = get_var_lnum(argvars);
5672     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
5673     {
5674 	curwin->w_cursor.lnum = lnum;
5675 	retvar->var_val.var_number = get_lisp_indent();
5676 	curwin->w_cursor = pos;
5677     }
5678     else
5679 #endif
5680 	retvar->var_val.var_number = -1;
5681 }
5682 
5683 /*
5684  * "localtime()" function
5685  */
5686 /*ARGSUSED*/
5687     static void
5688 f_localtime(argvars, retvar)
5689     VAR		argvars;
5690     VAR		retvar;
5691 {
5692     retvar->var_val.var_number = (varnumber_T)time(NULL);
5693 }
5694 
5695 /*
5696  * "maparg()" function
5697  */
5698     static void
5699 f_maparg(argvars, retvar)
5700     VAR		argvars;
5701     VAR		retvar;
5702 {
5703     get_maparg(argvars, retvar, TRUE);
5704 }
5705 
5706 /*
5707  * "mapcheck()" function
5708  */
5709     static void
5710 f_mapcheck(argvars, retvar)
5711     VAR		argvars;
5712     VAR		retvar;
5713 {
5714     get_maparg(argvars, retvar, FALSE);
5715 }
5716 
5717     static void
5718 get_maparg(argvars, retvar, exact)
5719     VAR		argvars;
5720     VAR		retvar;
5721     int		exact;
5722 {
5723     char_u	*keys;
5724     char_u	*which;
5725     char_u	buf[NUMBUFLEN];
5726     char_u	*keys_buf = NULL;
5727     char_u	*rhs;
5728     int		mode;
5729     garray_T	ga;
5730 
5731     /* return empty string for failure */
5732     retvar->var_type = VAR_STRING;
5733     retvar->var_val.var_string = NULL;
5734 
5735     keys = get_var_string(&argvars[0]);
5736     if (*keys == NUL)
5737 	return;
5738 
5739     if (argvars[1].var_type != VAR_UNKNOWN)
5740 	which = get_var_string_buf(&argvars[1], buf);
5741     else
5742 	which = (char_u *)"";
5743     mode = get_map_mode(&which, 0);
5744 
5745     keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE);
5746     rhs = check_map(keys, mode, exact);
5747     vim_free(keys_buf);
5748     if (rhs != NULL)
5749     {
5750 	ga_init(&ga);
5751 	ga.ga_itemsize = 1;
5752 	ga.ga_growsize = 40;
5753 
5754 	while (*rhs != NUL)
5755 	    ga_concat(&ga, str2special(&rhs, FALSE));
5756 
5757 	ga_append(&ga, NUL);
5758 	retvar->var_val.var_string = (char_u *)ga.ga_data;
5759     }
5760 }
5761 
5762 /*
5763  * "match()" function
5764  */
5765     static void
5766 f_match(argvars, retvar)
5767     VAR		argvars;
5768     VAR		retvar;
5769 {
5770     find_some_match(argvars, retvar, 1);
5771 }
5772 
5773 /*
5774  * "matchend()" function
5775  */
5776     static void
5777 f_matchend(argvars, retvar)
5778     VAR		argvars;
5779     VAR		retvar;
5780 {
5781     find_some_match(argvars, retvar, 0);
5782 }
5783 
5784 /*
5785  * "matchstr()" function
5786  */
5787     static void
5788 f_matchstr(argvars, retvar)
5789     VAR		argvars;
5790     VAR		retvar;
5791 {
5792     find_some_match(argvars, retvar, 2);
5793 }
5794 
5795     static void
5796 find_some_match(argvars, retvar, type)
5797     VAR		argvars;
5798     VAR		retvar;
5799     int		type;
5800 {
5801     char_u	*str;
5802     char_u	*pat;
5803     regmatch_T	regmatch;
5804     char_u	patbuf[NUMBUFLEN];
5805     char_u	*save_cpo;
5806     long	start = 0;
5807 
5808     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
5809     save_cpo = p_cpo;
5810     p_cpo = (char_u *)"";
5811 
5812     str = get_var_string(&argvars[0]);
5813     pat = get_var_string_buf(&argvars[1], patbuf);
5814 
5815     if (type == 2)
5816     {
5817 	retvar->var_type = VAR_STRING;
5818 	retvar->var_val.var_string = NULL;
5819     }
5820     else
5821 	retvar->var_val.var_number = -1;
5822 
5823     if (argvars[2].var_type != VAR_UNKNOWN)
5824     {
5825 	start = get_var_number(&argvars[2]);
5826 	if (start < 0)
5827 	    start = 0;
5828 	if (start > (long)STRLEN(str))
5829 	    goto theend;
5830 	str += start;
5831     }
5832 
5833     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
5834     if (regmatch.regprog != NULL)
5835     {
5836 	regmatch.rm_ic = p_ic;
5837 	if (vim_regexec_nl(&regmatch, str, (colnr_T)0))
5838 	{
5839 	    if (type == 2)
5840 		retvar->var_val.var_string = vim_strnsave(regmatch.startp[0],
5841 				(int)(regmatch.endp[0] - regmatch.startp[0]));
5842 	    else
5843 	    {
5844 		if (type != 0)
5845 		    retvar->var_val.var_number =
5846 				      (varnumber_T)(regmatch.startp[0] - str);
5847 		else
5848 		    retvar->var_val.var_number =
5849 					(varnumber_T)(regmatch.endp[0] - str);
5850 		retvar->var_val.var_number += start;
5851 	    }
5852 	}
5853 	vim_free(regmatch.regprog);
5854     }
5855 
5856 theend:
5857     p_cpo = save_cpo;
5858 }
5859 
5860 /*
5861  * "mode()" function
5862  */
5863 /*ARGSUSED*/
5864     static void
5865 f_mode(argvars, retvar)
5866     VAR		argvars;
5867     VAR		retvar;
5868 {
5869     char_u	buf[2];
5870 
5871 #ifdef FEAT_VISUAL
5872     if (VIsual_active)
5873     {
5874 	if (VIsual_select)
5875 	    buf[0] = VIsual_mode + 's' - 'v';
5876 	else
5877 	    buf[0] = VIsual_mode;
5878     }
5879     else
5880 #endif
5881 	if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
5882 	buf[0] = 'r';
5883     else if (State & INSERT)
5884     {
5885 	if (State & REPLACE_FLAG)
5886 	    buf[0] = 'R';
5887 	else
5888 	    buf[0] = 'i';
5889     }
5890     else if (State & CMDLINE)
5891 	buf[0] = 'c';
5892     else
5893 	buf[0] = 'n';
5894 
5895     buf[1] = NUL;
5896     retvar->var_val.var_string = vim_strsave(buf);
5897     retvar->var_type = VAR_STRING;
5898 }
5899 
5900 /*
5901  * "nr2char()" function
5902  */
5903     static void
5904 f_nr2char(argvars, retvar)
5905     VAR		argvars;
5906     VAR		retvar;
5907 {
5908     char_u	buf[NUMBUFLEN];
5909 
5910 #ifdef FEAT_MBYTE
5911     if (has_mbyte)
5912 	buf[(*mb_char2bytes)((int)get_var_number(&argvars[0]), buf)] = NUL;
5913     else
5914 #endif
5915     {
5916 	buf[0] = (char_u)get_var_number(&argvars[0]);
5917 	buf[1] = NUL;
5918     }
5919     retvar->var_type = VAR_STRING;
5920     retvar->var_val.var_string = vim_strsave(buf);
5921 }
5922 
5923 /*
5924  * "rename({from}, {to})" function
5925  */
5926     static void
5927 f_rename(argvars, retvar)
5928     VAR		argvars;
5929     VAR		retvar;
5930 {
5931     char_u	buf[NUMBUFLEN];
5932 
5933     if (check_restricted() || check_secure())
5934 	retvar->var_val.var_number = -1;
5935     else
5936 	retvar->var_val.var_number = vim_rename(get_var_string(&argvars[0]),
5937 					get_var_string_buf(&argvars[1], buf));
5938 }
5939 
5940 /*
5941  * "resolve()" function
5942  */
5943     static void
5944 f_resolve(argvars, retvar)
5945     VAR		argvars;
5946     VAR		retvar;
5947 {
5948     char_u	*p;
5949 
5950     p = get_var_string(&argvars[0]);
5951 #ifdef FEAT_SHORTCUT
5952     {
5953 	char_u	*v = NULL;
5954 
5955 	v = mch_resolve_shortcut(p);
5956 	if (v != NULL)
5957 	    retvar->var_val.var_string = v;
5958 	else
5959 	    retvar->var_val.var_string = vim_strsave(p);
5960     }
5961 #else
5962 # ifdef HAVE_READLINK
5963     {
5964 	char_u	buf[MAXPATHL + 1];
5965 	char_u	*cpy;
5966 	int	len;
5967 	char_u	*remain = NULL;
5968 	char_u	*q;
5969 	int	is_relative_to_current = FALSE;
5970 	int	has_trailing_pathsep = FALSE;
5971 	int	limit = 100;
5972 
5973 	p = vim_strsave(p);
5974 
5975 	if (p[0] == '.' && (vim_ispathsep(p[1])
5976 				   || (p[1] == '.' && (vim_ispathsep(p[2])))))
5977 	    is_relative_to_current = TRUE;
5978 
5979 	len = STRLEN(p);
5980 	if (len > 0 && vim_ispathsep(p[len-1]))
5981 	    has_trailing_pathsep = TRUE;
5982 
5983 	q = getnextcomp(p);
5984 	if (*q != NUL)
5985 	{
5986 	    /* Separate the first path component in "p", and keep the
5987 	     * remainder (beginning with the path separator). */
5988 	    remain = vim_strsave(q - 1);
5989 	    q[-1] = NUL;
5990 	}
5991 
5992 	for (;;)
5993 	{
5994 	    for (;;)
5995 	    {
5996 		len = readlink((char *)p, (char *)buf, MAXPATHL);
5997 		if (len <= 0)
5998 		    break;
5999 		buf[len] = NUL;
6000 
6001 		if (limit-- == 0)
6002 		{
6003 		    vim_free(p);
6004 		    vim_free(remain);
6005 		    EMSG(_("E655: Too many symbolic links (cycle?)"));
6006 		    retvar->var_val.var_string = NULL;
6007 		    goto fail;
6008 		}
6009 
6010 		/* Ensure that the result will have a trailing path separator
6011 		 * if the argument has one. */
6012 		if (remain == NULL && has_trailing_pathsep)
6013 		    add_pathsep(buf);
6014 
6015 		/* Separate the first path component in the link value and
6016 		 * concatenate the remainders. */
6017 		q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf);
6018 		if (*q != NUL)
6019 		{
6020 		    if (remain == NULL)
6021 			remain = vim_strsave(q - 1);
6022 		    else
6023 		    {
6024 			cpy = vim_strnsave(q-1, STRLEN(q-1)+STRLEN(remain));
6025 			if (cpy != NULL)
6026 			{
6027 			    STRCAT(cpy, remain);
6028 			    vim_free(remain);
6029 			    remain = cpy;
6030 			}
6031 		    }
6032 		    q[-1] = NUL;
6033 		}
6034 
6035 		q = gettail(p);
6036 		if (q > p && *q == NUL)
6037 		{
6038 		    /* Ignore trailing path separator. */
6039 		    q[-1] = NUL;
6040 		    q = gettail(p);
6041 		}
6042 		if (q > p && !mch_isFullName(buf))
6043 		{
6044 		    /* symlink is relative to directory of argument */
6045 		    cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1));
6046 		    if (cpy != NULL)
6047 		    {
6048 			STRCPY(cpy, p);
6049 			STRCPY(gettail(cpy), buf);
6050 			vim_free(p);
6051 			p = cpy;
6052 		    }
6053 		}
6054 		else
6055 		{
6056 		    vim_free(p);
6057 		    p = vim_strsave(buf);
6058 		}
6059 	    }
6060 
6061 	    if (remain == NULL)
6062 		break;
6063 
6064 	    /* Append the first path component of "remain" to "p". */
6065 	    q = getnextcomp(remain + 1);
6066 	    len = q - remain - (*q != NUL);
6067 	    cpy = vim_strnsave(p, STRLEN(p) + len);
6068 	    if (cpy != NULL)
6069 	    {
6070 		STRNCAT(cpy, remain, len);
6071 		vim_free(p);
6072 		p = cpy;
6073 	    }
6074 	    /* Shorten "remain". */
6075 	    if (*q != NUL)
6076 		STRCPY(remain, q - 1);
6077 	    else
6078 	    {
6079 		vim_free(remain);
6080 		remain = NULL;
6081 	    }
6082 	}
6083 
6084 	/* If the result is a relative path name, make it explicitly relative to
6085 	 * the current directory if and only if the argument had this form. */
6086 	if (!vim_ispathsep(*p))
6087 	{
6088 	    if (is_relative_to_current
6089 		    && *p != NUL
6090 		    && !(p[0] == '.'
6091 			&& (p[1] == NUL
6092 			    || vim_ispathsep(p[1])
6093 			    || (p[1] == '.'
6094 				&& (p[2] == NUL
6095 				    || vim_ispathsep(p[2]))))))
6096 	    {
6097 		/* Prepend "./". */
6098 		cpy = vim_strnsave((char_u *)"./", 2 + STRLEN(p));
6099 		if (cpy != NULL)
6100 		{
6101 		    STRCAT(cpy, p);
6102 		    vim_free(p);
6103 		    p = cpy;
6104 		}
6105 	    }
6106 	    else if (!is_relative_to_current)
6107 	    {
6108 		/* Strip leading "./". */
6109 		q = p;
6110 		while (q[0] == '.' && vim_ispathsep(q[1]))
6111 		    q += 2;
6112 		if (q > p)
6113 		    mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1);
6114 	    }
6115 	}
6116 
6117 	/* Ensure that the result will have no trailing path separator
6118 	 * if the argument had none.  But keep "/" or "//". */
6119 	if (!has_trailing_pathsep)
6120 	{
6121 	    q = p + STRLEN(p);
6122 	    while ((q > p + 2 || (q == p + 2 && !vim_ispathsep(*p)))
6123 		   && vim_ispathsep(q[-1]))
6124 		--q;
6125 	    *q = NUL;
6126 	}
6127 
6128 	retvar->var_val.var_string = p;
6129     }
6130 # else
6131     retvar->var_val.var_string = vim_strsave(p);
6132 # endif
6133 #endif
6134 
6135     simplify_filename(retvar->var_val.var_string);
6136 
6137 #ifdef HAVE_READLINK
6138 fail:
6139 #endif
6140     retvar->var_type = VAR_STRING;
6141 }
6142 
6143 /*
6144  * "simplify()" function
6145  */
6146     static void
6147 f_simplify(argvars, retvar)
6148     VAR		argvars;
6149     VAR		retvar;
6150 {
6151     char_u	*p;
6152 
6153     p = get_var_string(&argvars[0]);
6154     retvar->var_val.var_string = vim_strsave(p);
6155     simplify_filename(retvar->var_val.var_string);	/* simplify in place */
6156     retvar->var_type = VAR_STRING;
6157 }
6158 
6159 /*
6160  * "search()" function
6161  */
6162     static void
6163 f_search(argvars, retvar)
6164     VAR		argvars;
6165     VAR		retvar;
6166 {
6167     char_u	*pat;
6168     pos_T	pos;
6169     int		save_p_ws = p_ws;
6170     int		dir;
6171 
6172     pat = get_var_string(&argvars[0]);
6173     dir = get_search_arg(&argvars[1], NULL);	/* may set p_ws */
6174 
6175     pos = curwin->w_cursor;
6176     if (searchit(curwin, curbuf, &pos, dir, pat, 1L,
6177 					      SEARCH_KEEP, RE_SEARCH) != FAIL)
6178     {
6179 	retvar->var_val.var_number = pos.lnum;
6180 	curwin->w_cursor = pos;
6181 	/* "/$" will put the cursor after the end of the line, may need to
6182 	 * correct that here */
6183 	check_cursor();
6184     }
6185     else
6186 	retvar->var_val.var_number = 0;
6187     p_ws = save_p_ws;
6188 }
6189 
6190 #define SP_NOMOVE	1	/* don't move cursor */
6191 #define SP_REPEAT	2	/* repeat to find outer pair */
6192 #define SP_RETCOUNT	4	/* return matchcount */
6193 
6194 /*
6195  * "searchpair()" function
6196  */
6197     static void
6198 f_searchpair(argvars, retvar)
6199     VAR		argvars;
6200     VAR		retvar;
6201 {
6202     char_u	*spat, *mpat, *epat;
6203     char_u	*skip;
6204     char_u	*pat, *pat2, *pat3;
6205     pos_T	pos;
6206     pos_T	firstpos;
6207     pos_T	save_cursor;
6208     pos_T	save_pos;
6209     int		save_p_ws = p_ws;
6210     char_u	*save_cpo;
6211     int		dir;
6212     int		flags = 0;
6213     char_u	nbuf1[NUMBUFLEN];
6214     char_u	nbuf2[NUMBUFLEN];
6215     char_u	nbuf3[NUMBUFLEN];
6216     int		n;
6217     int		r;
6218     int		nest = 1;
6219     int		err;
6220 
6221     retvar->var_val.var_number = 0;	/* default: FAIL */
6222 
6223     /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
6224     save_cpo = p_cpo;
6225     p_cpo = (char_u *)"";
6226 
6227     /* Get the three pattern arguments: start, middle, end. */
6228     spat = get_var_string(&argvars[0]);
6229     mpat = get_var_string_buf(&argvars[1], nbuf1);
6230     epat = get_var_string_buf(&argvars[2], nbuf2);
6231 
6232     /* Make two search patterns: start/end (pat2, for in nested pairs) and
6233      * start/middle/end (pat3, for the top pair). */
6234     pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
6235     pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
6236     if (pat2 == NULL || pat3 == NULL)
6237 	goto theend;
6238     sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
6239     if (*mpat == NUL)
6240 	STRCPY(pat3, pat2);
6241     else
6242 	sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
6243 							    spat, epat, mpat);
6244 
6245     /* Handle the optional fourth argument: flags */
6246     dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
6247 
6248     /* Optional fifth argument: skip expresion */
6249     if (argvars[3].var_type == VAR_UNKNOWN
6250 	    || argvars[4].var_type == VAR_UNKNOWN)
6251 	skip = (char_u *)"";
6252     else
6253 	skip = get_var_string_buf(&argvars[4], nbuf3);
6254 
6255     save_cursor = curwin->w_cursor;
6256     pos = curwin->w_cursor;
6257     firstpos.lnum = 0;
6258     pat = pat3;
6259     for (;;)
6260     {
6261 	n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
6262 						      SEARCH_KEEP, RE_SEARCH);
6263 	if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
6264 	    /* didn't find it or found the first match again: FAIL */
6265 	    break;
6266 
6267 	if (firstpos.lnum == 0)
6268 	    firstpos = pos;
6269 
6270 	/* If the skip pattern matches, ignore this match. */
6271 	if (*skip != NUL)
6272 	{
6273 	    save_pos = curwin->w_cursor;
6274 	    curwin->w_cursor = pos;
6275 	    r = eval_to_bool(skip, &err, NULL, FALSE);
6276 	    curwin->w_cursor = save_pos;
6277 	    if (err)
6278 	    {
6279 		/* Evaluating {skip} caused an error, break here. */
6280 		curwin->w_cursor = save_cursor;
6281 		retvar->var_val.var_number = -1;
6282 		break;
6283 	    }
6284 	    if (r)
6285 		continue;
6286 	}
6287 
6288 	if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2))
6289 	{
6290 	    /* Found end when searching backwards or start when searching
6291 	     * forward: nested pair. */
6292 	    ++nest;
6293 	    pat = pat2;		/* nested, don't search for middle */
6294 	}
6295 	else
6296 	{
6297 	    /* Found end when searching forward or start when searching
6298 	     * backward: end of (nested) pair; or found middle in outer pair. */
6299 	    if (--nest == 1)
6300 		pat = pat3;	/* outer level, search for middle */
6301 	}
6302 
6303 	if (nest == 0)
6304 	{
6305 	    /* Found the match: return matchcount or line number. */
6306 	    if (flags & SP_RETCOUNT)
6307 		++retvar->var_val.var_number;
6308 	    else
6309 		retvar->var_val.var_number = pos.lnum;
6310 	    curwin->w_cursor = pos;
6311 	    if (!(flags & SP_REPEAT))
6312 		break;
6313 	    nest = 1;	    /* search for next unmatched */
6314 	}
6315     }
6316 
6317     /* If 'n' flag is used or search failed: restore cursor position. */
6318     if ((flags & SP_NOMOVE) || retvar->var_val.var_number == 0)
6319 	curwin->w_cursor = save_cursor;
6320 
6321 theend:
6322     vim_free(pat2);
6323     vim_free(pat3);
6324     p_ws = save_p_ws;
6325     p_cpo = save_cpo;
6326 }
6327 
6328     static int
6329 get_search_arg(varp, flagsp)
6330     VAR		varp;
6331     int		*flagsp;
6332 {
6333     int		dir = FORWARD;
6334     char_u	*flags;
6335     char_u	nbuf[NUMBUFLEN];
6336 
6337     if (varp->var_type != VAR_UNKNOWN)
6338     {
6339 	flags = get_var_string_buf(varp, nbuf);
6340 	if (vim_strchr(flags, 'b') != NULL)
6341 	    dir = BACKWARD;
6342 	if (vim_strchr(flags, 'w') != NULL)
6343 	    p_ws = TRUE;
6344 	if (vim_strchr(flags, 'W') != NULL)
6345 	    p_ws = FALSE;
6346 	if (flagsp != NULL)
6347 	{
6348 	    if (vim_strchr(flags, 'n') != NULL)
6349 		*flagsp |= SP_NOMOVE;
6350 	    if (vim_strchr(flags, 'r') != NULL)
6351 		*flagsp |= SP_REPEAT;
6352 	    if (vim_strchr(flags, 'm') != NULL)
6353 		*flagsp |= SP_RETCOUNT;
6354 	}
6355     }
6356     return dir;
6357 }
6358 
6359 /*
6360  * "setbufvar()" function
6361  */
6362 /*ARGSUSED*/
6363     static void
6364 f_setbufvar(argvars, retvar)
6365     VAR		argvars;
6366     VAR		retvar;
6367 {
6368     buf_T	*buf;
6369 #ifdef FEAT_AUTOCMD
6370     aco_save_T	aco;
6371 #else
6372     buf_T	*save_curbuf;
6373 #endif
6374     char_u	*varname, *bufvarname;
6375     VAR		varp;
6376     char_u	nbuf[NUMBUFLEN];
6377 
6378     if (check_restricted() || check_secure())
6379 	return;
6380     ++emsg_off;
6381     buf = get_buf_var(&argvars[0]);
6382     varname = get_var_string(&argvars[1]);
6383     varp = &argvars[2];
6384 
6385     if (buf != NULL && varname != NULL && varp != NULL)
6386     {
6387 	/* set curbuf to be our buf, temporarily */
6388 #ifdef FEAT_AUTOCMD
6389 	aucmd_prepbuf(&aco, buf);
6390 #else
6391 	save_curbuf = curbuf;
6392 	curbuf = buf;
6393 #endif
6394 
6395 	if (*varname == '&')
6396 	{
6397 	    ++varname;
6398 	    set_option_value(varname, get_var_number(varp),
6399 				   get_var_string_buf(varp, nbuf), OPT_LOCAL);
6400 	}
6401 	else
6402 	{
6403 	    bufvarname = alloc((unsigned)STRLEN(varname) + 3);
6404 	    if (bufvarname != NULL)
6405 	    {
6406 		STRCPY(bufvarname, "b:");
6407 		STRCPY(bufvarname + 2, varname);
6408 		set_var(bufvarname, varp);
6409 		vim_free(bufvarname);
6410 	    }
6411 	}
6412 
6413 	/* reset notion of buffer */
6414 #ifdef FEAT_AUTOCMD
6415 	aucmd_restbuf(&aco);
6416 #else
6417 	curbuf = save_curbuf;
6418 #endif
6419     }
6420     --emsg_off;
6421 }
6422 
6423 /*
6424  * "setcmdpos()" function
6425  */
6426     static void
6427 f_setcmdpos(argvars, retvar)
6428     VAR		argvars;
6429     VAR		retvar;
6430 {
6431     retvar->var_val.var_number = set_cmdline_pos(
6432 					(int)get_var_number(&argvars[0]) - 1);
6433 }
6434 
6435 /*
6436  * "setline()" function
6437  */
6438     static void
6439 f_setline(argvars, retvar)
6440     VAR		argvars;
6441     VAR		retvar;
6442 {
6443     linenr_T	lnum;
6444     char_u	*line;
6445 
6446     lnum = get_var_lnum(argvars);
6447     line = get_var_string(&argvars[1]);
6448     retvar->var_val.var_number = 1;		/* FAIL is default */
6449 
6450     if (lnum >= 1
6451 	    && lnum <= curbuf->b_ml.ml_line_count
6452 	    && u_savesub(lnum) == OK
6453 	    && ml_replace(lnum, line, TRUE) == OK)
6454     {
6455 	changed_bytes(lnum, 0);
6456 	check_cursor_col();
6457 	retvar->var_val.var_number = 0;
6458     }
6459 }
6460 
6461 /*
6462  * "setreg()" function
6463  */
6464     static void
6465 f_setreg(argvars, retvar)
6466     VAR		argvars;
6467     VAR		retvar;
6468 {
6469     int		regname;
6470     char_u	*strregname;
6471     char_u	*stropt;
6472     int		append;
6473     char_u	yank_type;
6474     long	block_len;
6475 
6476     block_len = -1;
6477     yank_type = MAUTO;
6478     append = FALSE;
6479 
6480     strregname = get_var_string(argvars);
6481     retvar->var_val.var_number = 1;		/* FAIL is default */
6482 
6483     regname = (strregname == NULL ? '"' : *strregname);
6484     if (regname == 0 || regname == '@')
6485 	regname = '"';
6486     else if (regname == '=')
6487 	return;
6488 
6489     if (argvars[2].var_type != VAR_UNKNOWN)
6490     {
6491 	for (stropt = get_var_string(&argvars[2]); *stropt != NUL; ++stropt)
6492 	    switch (*stropt)
6493 	    {
6494 		case 'a': case 'A':	/* append */
6495 		    append = TRUE;
6496 		    break;
6497 		case 'v': case 'c':	/* character-wise selection */
6498 		    yank_type = MCHAR;
6499 		    break;
6500 		case 'V': case 'l':	/* line-wise selection */
6501 		    yank_type = MLINE;
6502 		    break;
6503 #ifdef FEAT_VISUAL
6504 		case 'b': case Ctrl_V:	/* block-wise selection */
6505 		    yank_type = MBLOCK;
6506 		    if (VIM_ISDIGIT(stropt[1]))
6507 		    {
6508 			++stropt;
6509 			block_len = getdigits(&stropt) - 1;
6510 			--stropt;
6511 		    }
6512 		    break;
6513 #endif
6514 	    }
6515     }
6516 
6517     write_reg_contents_ex(regname, get_var_string(&argvars[1]), -1,
6518 						append, yank_type, block_len);
6519     retvar->var_val.var_number = 0;
6520 }
6521 
6522 
6523 /*
6524  * "setwinvar(expr)" function
6525  */
6526 /*ARGSUSED*/
6527     static void
6528 f_setwinvar(argvars, retvar)
6529     VAR		argvars;
6530     VAR		retvar;
6531 {
6532     win_T	*win;
6533 #ifdef FEAT_WINDOWS
6534     win_T	*save_curwin;
6535 #endif
6536     char_u	*varname, *winvarname;
6537     VAR		varp;
6538     char_u	nbuf[NUMBUFLEN];
6539 
6540     if (check_restricted() || check_secure())
6541 	return;
6542     ++emsg_off;
6543     win = find_win_by_nr(&argvars[0]);
6544     varname = get_var_string(&argvars[1]);
6545     varp = &argvars[2];
6546 
6547     if (win != NULL && varname != NULL && varp != NULL)
6548     {
6549 #ifdef FEAT_WINDOWS
6550 	/* set curwin to be our win, temporarily */
6551 	save_curwin = curwin;
6552 	curwin = win;
6553 	curbuf = curwin->w_buffer;
6554 #endif
6555 
6556 	if (*varname == '&')
6557 	{
6558 	    ++varname;
6559 	    set_option_value(varname, get_var_number(varp),
6560 				   get_var_string_buf(varp, nbuf), OPT_LOCAL);
6561 	}
6562 	else
6563 	{
6564 	    winvarname = alloc((unsigned)STRLEN(varname) + 3);
6565 	    if (winvarname != NULL)
6566 	    {
6567 		STRCPY(winvarname, "w:");
6568 		STRCPY(winvarname + 2, varname);
6569 		set_var(winvarname, varp);
6570 		vim_free(winvarname);
6571 	    }
6572 	}
6573 
6574 #ifdef FEAT_WINDOWS
6575 	/* Restore current window, if it's still valid (autocomands can make
6576 	 * it invalid). */
6577 	if (win_valid(save_curwin))
6578 	{
6579 	    curwin = save_curwin;
6580 	    curbuf = curwin->w_buffer;
6581 	}
6582 #endif
6583     }
6584     --emsg_off;
6585 }
6586 
6587 /*
6588  * "nextnonblank()" function
6589  */
6590     static void
6591 f_nextnonblank(argvars, retvar)
6592     VAR		argvars;
6593     VAR		retvar;
6594 {
6595     linenr_T	lnum;
6596 
6597     for (lnum = get_var_lnum(argvars); ; ++lnum)
6598     {
6599 	if (lnum > curbuf->b_ml.ml_line_count)
6600 	{
6601 	    lnum = 0;
6602 	    break;
6603 	}
6604 	if (*skipwhite(ml_get(lnum)) != NUL)
6605 	    break;
6606     }
6607     retvar->var_val.var_number = lnum;
6608 }
6609 
6610 /*
6611  * "prevnonblank()" function
6612  */
6613     static void
6614 f_prevnonblank(argvars, retvar)
6615     VAR		argvars;
6616     VAR		retvar;
6617 {
6618     linenr_T	lnum;
6619 
6620     lnum = get_var_lnum(argvars);
6621     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
6622 	lnum = 0;
6623     else
6624 	while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
6625 	    --lnum;
6626     retvar->var_val.var_number = lnum;
6627 }
6628 
6629 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
6630 static void make_connection __ARGS((void));
6631 static int check_connection __ARGS((void));
6632 
6633     static void
6634 make_connection()
6635 {
6636     if (X_DISPLAY == NULL
6637 # ifdef FEAT_GUI
6638 	    && !gui.in_use
6639 # endif
6640 	    )
6641     {
6642 	x_force_connect = TRUE;
6643 	setup_term_clip();
6644 	x_force_connect = FALSE;
6645     }
6646 }
6647 
6648     static int
6649 check_connection()
6650 {
6651     make_connection();
6652     if (X_DISPLAY == NULL)
6653     {
6654 	EMSG(_("E240: No connection to Vim server"));
6655 	return FAIL;
6656     }
6657     return OK;
6658 }
6659 #endif
6660 
6661 /*ARGSUSED*/
6662     static void
6663 f_serverlist(argvars, retvar)
6664     VAR		argvars;
6665     VAR		retvar;
6666 {
6667     char_u	*r = NULL;
6668 
6669 #ifdef FEAT_CLIENTSERVER
6670 # ifdef WIN32
6671     r = serverGetVimNames();
6672 # else
6673     make_connection();
6674     if (X_DISPLAY != NULL)
6675 	r = serverGetVimNames(X_DISPLAY);
6676 # endif
6677 #endif
6678     retvar->var_type = VAR_STRING;
6679     retvar->var_val.var_string = r;
6680 }
6681 
6682 /*ARGSUSED*/
6683     static void
6684 f_remote_peek(argvars, retvar)
6685     VAR		argvars;
6686     VAR		retvar;
6687 {
6688 #ifdef FEAT_CLIENTSERVER
6689     var		v;
6690     char_u	*s = NULL;
6691 # ifdef WIN32
6692     int		n = 0;
6693 # endif
6694 
6695     if (check_restricted() || check_secure())
6696     {
6697 	retvar->var_val.var_number = -1;
6698 	return;
6699     }
6700 # ifdef WIN32
6701     sscanf(get_var_string(&argvars[0]), "%x", &n);
6702     if (n == 0)
6703 	retvar->var_val.var_number = -1;
6704     else
6705     {
6706 	s = serverGetReply((HWND)n, FALSE, FALSE, FALSE);
6707 	retvar->var_val.var_number = (s != NULL);
6708     }
6709 # else
6710     retvar->var_val.var_number = 0;
6711     if (check_connection() == FAIL)
6712 	return;
6713 
6714     retvar->var_val.var_number = serverPeekReply(X_DISPLAY,
6715 			     serverStrToWin(get_var_string(&argvars[0])), &s);
6716 # endif
6717 
6718     if (argvars[1].var_type != VAR_UNKNOWN && retvar->var_val.var_number > 0)
6719     {
6720 	v.var_type = VAR_STRING;
6721 	v.var_val.var_string = vim_strsave(s);
6722 	set_var(get_var_string(&argvars[1]), &v);
6723     }
6724 #else
6725     retvar->var_val.var_number = -1;
6726 #endif
6727 }
6728 
6729 /*ARGSUSED*/
6730     static void
6731 f_remote_read(argvars, retvar)
6732     VAR		argvars;
6733     VAR		retvar;
6734 {
6735     char_u	*r = NULL;
6736 
6737 #ifdef FEAT_CLIENTSERVER
6738     if (!check_restricted() && !check_secure())
6739     {
6740 # ifdef WIN32
6741 	/* The server's HWND is encoded in the 'id' parameter */
6742 	int		n = 0;
6743 
6744 	sscanf(get_var_string(&argvars[0]), "%x", &n);
6745 	if (n != 0)
6746 	    r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
6747 	if (r == NULL)
6748 # else
6749 	if (check_connection() == FAIL || serverReadReply(X_DISPLAY,
6750 		  serverStrToWin(get_var_string(&argvars[0])), &r, FALSE) < 0)
6751 # endif
6752 	    EMSG(_("E277: Unable to read a server reply"));
6753     }
6754 #endif
6755     retvar->var_type = VAR_STRING;
6756     retvar->var_val.var_string = r;
6757 }
6758 
6759 /*ARGSUSED*/
6760     static void
6761 f_server2client(argvars, retvar)
6762     VAR		argvars;
6763     VAR		retvar;
6764 {
6765 #ifdef FEAT_CLIENTSERVER
6766     char_u	buf[NUMBUFLEN];
6767     char_u	*server = get_var_string(&argvars[0]);
6768     char_u	*reply = get_var_string_buf(&argvars[1], buf);
6769 
6770     retvar->var_val.var_number = -1;
6771     if (check_restricted() || check_secure())
6772 	return;
6773 # ifdef FEAT_X11
6774     if (check_connection() == FAIL)
6775 	return;
6776 # endif
6777 
6778     if (serverSendReply(server, reply) < 0)
6779     {
6780 	EMSG(_("E258: Unable to send to client"));
6781 	return;
6782     }
6783     retvar->var_val.var_number = 0;
6784 #else
6785     retvar->var_val.var_number = -1;
6786 #endif
6787 }
6788 
6789 #ifdef FEAT_CLIENTSERVER
6790 static void remote_common __ARGS((VAR argvars, VAR retvar, int expr));
6791 
6792     static void
6793 remote_common(argvars, retvar, expr)
6794     VAR		argvars;
6795     VAR		retvar;
6796     int		expr;
6797 {
6798     char_u	*server_name;
6799     char_u	*keys;
6800     char_u	*r = NULL;
6801     char_u	buf[NUMBUFLEN];
6802 # ifdef WIN32
6803     HWND	w;
6804 # else
6805     Window	w;
6806 # endif
6807 
6808     if (check_restricted() || check_secure())
6809 	return;
6810 
6811 # ifdef FEAT_X11
6812     if (check_connection() == FAIL)
6813 	return;
6814 # endif
6815 
6816     server_name = get_var_string(&argvars[0]);
6817     keys = get_var_string_buf(&argvars[1], buf);
6818 # ifdef WIN32
6819     if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0)
6820 # else
6821     if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE)
6822 									  < 0)
6823 # endif
6824     {
6825 	if (r != NULL)
6826 	    EMSG(r);		/* sending worked but evaluation failed */
6827 	else
6828 	    EMSG2(_("E241: Unable to send to %s"), server_name);
6829 	return;
6830     }
6831 
6832     retvar->var_val.var_string = r;
6833 
6834     if (argvars[2].var_type != VAR_UNKNOWN)
6835     {
6836 	var	v;
6837 	char_u	str[30];
6838 
6839 	sprintf((char *)str, "0x%x", (unsigned int)w);
6840 	v.var_type = VAR_STRING;
6841 	v.var_val.var_string = vim_strsave(str);
6842 	set_var(get_var_string(&argvars[2]), &v);
6843     }
6844 }
6845 #endif
6846 
6847 /*
6848  * "remote_expr()" function
6849  */
6850 /*ARGSUSED*/
6851     static void
6852 f_remote_expr(argvars, retvar)
6853     VAR		argvars;
6854     VAR		retvar;
6855 {
6856     retvar->var_type = VAR_STRING;
6857     retvar->var_val.var_string = NULL;
6858 #ifdef FEAT_CLIENTSERVER
6859     remote_common(argvars, retvar, TRUE);
6860 #endif
6861 }
6862 
6863 /*
6864  * "remote_send()" function
6865  */
6866 /*ARGSUSED*/
6867     static void
6868 f_remote_send(argvars, retvar)
6869     VAR		argvars;
6870     VAR		retvar;
6871 {
6872     retvar->var_type = VAR_STRING;
6873     retvar->var_val.var_string = NULL;
6874 #ifdef FEAT_CLIENTSERVER
6875     remote_common(argvars, retvar, FALSE);
6876 #endif
6877 }
6878 
6879 /*
6880  * "remote_foreground()" function
6881  */
6882 /*ARGSUSED*/
6883     static void
6884 f_remote_foreground(argvars, retvar)
6885     VAR		argvars;
6886     VAR		retvar;
6887 {
6888     retvar->var_val.var_number = 0;
6889 #ifdef FEAT_CLIENTSERVER
6890 # ifdef WIN32
6891     /* On Win32 it's done in this application. */
6892     serverForeground(get_var_string(&argvars[0]));
6893 # else
6894     /* Send a foreground() expression to the server. */
6895     argvars[1].var_type = VAR_STRING;
6896     argvars[1].var_val.var_string = vim_strsave((char_u *)"foreground()");
6897     argvars[2].var_type = VAR_UNKNOWN;
6898     remote_common(argvars, retvar, TRUE);
6899     vim_free(argvars[1].var_val.var_string);
6900 # endif
6901 #endif
6902 }
6903 
6904 #ifdef HAVE_STRFTIME
6905 /*
6906  * "strftime({format}[, {time}])" function
6907  */
6908     static void
6909 f_strftime(argvars, retvar)
6910     VAR		argvars;
6911     VAR		retvar;
6912 {
6913     char_u	result_buf[256];
6914     struct tm	*curtime;
6915     time_t	seconds;
6916     char_u	*p;
6917 
6918     retvar->var_type = VAR_STRING;
6919 
6920     p = get_var_string(&argvars[0]);
6921     if (argvars[1].var_type == VAR_UNKNOWN)
6922 	seconds = time(NULL);
6923     else
6924 	seconds = (time_t)get_var_number(&argvars[1]);
6925     curtime = localtime(&seconds);
6926     /* MSVC returns NULL for an invalid value of seconds. */
6927     if (curtime == NULL)
6928 	retvar->var_val.var_string = vim_strsave((char_u *)_("(Invalid)"));
6929     else
6930     {
6931 # ifdef FEAT_MBYTE
6932 	vimconv_T   conv;
6933 	char_u	    *enc;
6934 
6935 	conv.vc_type = CONV_NONE;
6936 	enc = enc_locale();
6937 	convert_setup(&conv, p_enc, enc);
6938 	if (conv.vc_type != CONV_NONE)
6939 	    p = string_convert(&conv, p, NULL);
6940 # endif
6941 	if (p != NULL)
6942 	    (void)strftime((char *)result_buf, sizeof(result_buf),
6943 							  (char *)p, curtime);
6944 	else
6945 	    result_buf[0] = NUL;
6946 
6947 # ifdef FEAT_MBYTE
6948 	if (conv.vc_type != CONV_NONE)
6949 	    vim_free(p);
6950 	convert_setup(&conv, enc, p_enc);
6951 	if (conv.vc_type != CONV_NONE)
6952 	    retvar->var_val.var_string =
6953 				      string_convert(&conv, result_buf, NULL);
6954 	else
6955 # endif
6956 	    retvar->var_val.var_string = vim_strsave(result_buf);
6957 
6958 # ifdef FEAT_MBYTE
6959 	/* Release conversion descriptors */
6960 	convert_setup(&conv, NULL, NULL);
6961 	vim_free(enc);
6962 # endif
6963     }
6964 }
6965 #endif
6966 
6967 /*
6968  * "stridx()" function
6969  */
6970     static void
6971 f_stridx(argvars, retvar)
6972     VAR		argvars;
6973     VAR		retvar;
6974 {
6975     char_u	buf[NUMBUFLEN];
6976     char_u	*needle;
6977     char_u	*haystack;
6978     char_u	*pos;
6979 
6980     needle = get_var_string(&argvars[1]);
6981     haystack = get_var_string_buf(&argvars[0], buf);
6982     pos	= (char_u *)strstr((char *)haystack, (char *)needle);
6983 
6984     if (pos == NULL)
6985 	retvar->var_val.var_number = -1;
6986     else
6987 	retvar->var_val.var_number = (varnumber_T) (pos - haystack);
6988 }
6989 
6990 /*
6991  * "strridx()" function
6992  */
6993     static void
6994 f_strridx(argvars, retvar)
6995     VAR		argvars;
6996     VAR		retvar;
6997 {
6998     char_u	buf[NUMBUFLEN];
6999     char_u	*needle;
7000     char_u	*haystack;
7001     char_u	*rest;
7002     char_u	*lastmatch = NULL;
7003 
7004     needle = get_var_string(&argvars[1]);
7005     haystack = get_var_string_buf(&argvars[0], buf);
7006     rest = haystack;
7007     while (*haystack != '\0')
7008     {
7009 	rest = (char_u *)strstr((char *)rest, (char *)needle);
7010 	if (rest == NULL)
7011 	    break;
7012 	lastmatch = rest++;
7013     }
7014 
7015     if (lastmatch == NULL)
7016 	retvar->var_val.var_number = -1;
7017     else
7018 	retvar->var_val.var_number = (varnumber_T) (lastmatch - haystack);
7019 }
7020 
7021 /*
7022  * "strlen()" function
7023  */
7024     static void
7025 f_strlen(argvars, retvar)
7026     VAR		argvars;
7027     VAR		retvar;
7028 {
7029     retvar->var_val.var_number = (varnumber_T) (STRLEN(get_var_string(&argvars[0])));
7030 }
7031 
7032 /*
7033  * "strpart()" function
7034  */
7035     static void
7036 f_strpart(argvars, retvar)
7037     VAR		argvars;
7038     VAR		retvar;
7039 {
7040     char_u	*p;
7041     int		n;
7042     int		len;
7043     int		slen;
7044 
7045     p = get_var_string(&argvars[0]);
7046     slen = (int)STRLEN(p);
7047 
7048     n = get_var_number(&argvars[1]);
7049     if (argvars[2].var_type != VAR_UNKNOWN)
7050 	len = get_var_number(&argvars[2]);
7051     else
7052 	len = slen - n;	    /* default len: all bytes that are available. */
7053 
7054     /*
7055      * Only return the overlap between the specified part and the actual
7056      * string.
7057      */
7058     if (n < 0)
7059     {
7060 	len += n;
7061 	n = 0;
7062     }
7063     else if (n > slen)
7064 	n = slen;
7065     if (len < 0)
7066 	len = 0;
7067     else if (n + len > slen)
7068 	len = slen - n;
7069 
7070     retvar->var_type = VAR_STRING;
7071     retvar->var_val.var_string = vim_strnsave(p + n, len);
7072 }
7073 
7074 /*
7075  * "strtrans()" function
7076  */
7077     static void
7078 f_strtrans(argvars, retvar)
7079     VAR		argvars;
7080     VAR		retvar;
7081 {
7082     retvar->var_type = VAR_STRING;
7083     retvar->var_val.var_string = transstr(get_var_string(&argvars[0]));
7084 }
7085 
7086 /*
7087  * "synID(line, col, trans)" function
7088  */
7089 /*ARGSUSED*/
7090     static void
7091 f_synID(argvars, retvar)
7092     VAR		argvars;
7093     VAR		retvar;
7094 {
7095     int		id = 0;
7096 #ifdef FEAT_SYN_HL
7097     long	line;
7098     long	col;
7099     int		trans;
7100 
7101     line = get_var_lnum(argvars);
7102     col = get_var_number(&argvars[1]) - 1;
7103     trans = get_var_number(&argvars[2]);
7104 
7105     if (line >= 1 && line <= curbuf->b_ml.ml_line_count
7106 	    && col >= 0 && col < (long)STRLEN(ml_get(line)))
7107 	id = syn_get_id(line, col, trans);
7108 #endif
7109 
7110     retvar->var_val.var_number = id;
7111 }
7112 
7113 /*
7114  * "synIDattr(id, what [, mode])" function
7115  */
7116 /*ARGSUSED*/
7117     static void
7118 f_synIDattr(argvars, retvar)
7119     VAR		argvars;
7120     VAR		retvar;
7121 {
7122     char_u	*p = NULL;
7123 #ifdef FEAT_SYN_HL
7124     int		id;
7125     char_u	*what;
7126     char_u	*mode;
7127     char_u	modebuf[NUMBUFLEN];
7128     int		modec;
7129 
7130     id = get_var_number(&argvars[0]);
7131     what = get_var_string(&argvars[1]);
7132     if (argvars[2].var_type != VAR_UNKNOWN)
7133     {
7134 	mode = get_var_string_buf(&argvars[2], modebuf);
7135 	modec = TOLOWER_ASC(mode[0]);
7136 	if (modec != 't' && modec != 'c'
7137 #ifdef FEAT_GUI
7138 		&& modec != 'g'
7139 #endif
7140 		)
7141 	    modec = 0;	/* replace invalid with current */
7142     }
7143     else
7144     {
7145 #ifdef FEAT_GUI
7146 	if (gui.in_use)
7147 	    modec = 'g';
7148 	else
7149 #endif
7150 	    if (t_colors > 1)
7151 	    modec = 'c';
7152 	else
7153 	    modec = 't';
7154     }
7155 
7156 
7157     switch (TOLOWER_ASC(what[0]))
7158     {
7159 	case 'b':
7160 		if (TOLOWER_ASC(what[1]) == 'g')	/* bg[#] */
7161 		    p = highlight_color(id, what, modec);
7162 		else					/* bold */
7163 		    p = highlight_has_attr(id, HL_BOLD, modec);
7164 		break;
7165 
7166 	case 'f':					/* fg[#] */
7167 		p = highlight_color(id, what, modec);
7168 		break;
7169 
7170 	case 'i':
7171 		if (TOLOWER_ASC(what[1]) == 'n')	/* inverse */
7172 		    p = highlight_has_attr(id, HL_INVERSE, modec);
7173 		else					/* italic */
7174 		    p = highlight_has_attr(id, HL_ITALIC, modec);
7175 		break;
7176 
7177 	case 'n':					/* name */
7178 		p = get_highlight_name(NULL, id - 1);
7179 		break;
7180 
7181 	case 'r':					/* reverse */
7182 		p = highlight_has_attr(id, HL_INVERSE, modec);
7183 		break;
7184 
7185 	case 's':					/* standout */
7186 		p = highlight_has_attr(id, HL_STANDOUT, modec);
7187 		break;
7188 
7189 	case 'u':					/* underline */
7190 		p = highlight_has_attr(id, HL_UNDERLINE, modec);
7191 		break;
7192     }
7193 
7194     if (p != NULL)
7195 	p = vim_strsave(p);
7196 #endif
7197     retvar->var_type = VAR_STRING;
7198     retvar->var_val.var_string = p;
7199 }
7200 
7201 /*
7202  * "synIDtrans(id)" function
7203  */
7204 /*ARGSUSED*/
7205     static void
7206 f_synIDtrans(argvars, retvar)
7207     VAR		argvars;
7208     VAR		retvar;
7209 {
7210     int		id;
7211 
7212 #ifdef FEAT_SYN_HL
7213     id = get_var_number(&argvars[0]);
7214 
7215     if (id > 0)
7216 	id = syn_get_final_id(id);
7217     else
7218 #endif
7219 	id = 0;
7220 
7221     retvar->var_val.var_number = id;
7222 }
7223 
7224 /*
7225  * "system()" function
7226  */
7227     static void
7228 f_system(argvars, retvar)
7229     VAR		argvars;
7230     VAR		retvar;
7231 {
7232     char_u	*p;
7233 
7234     p = get_cmd_output(get_var_string(&argvars[0]), SHELL_SILENT);
7235 #ifdef USE_CR
7236     /* translate <CR> into <NL> */
7237     if (p != NULL)
7238     {
7239 	char_u	*s;
7240 
7241 	for (s = p; *s; ++s)
7242 	{
7243 	    if (*s == CAR)
7244 		*s = NL;
7245 	}
7246     }
7247 #else
7248 # ifdef USE_CRNL
7249     /* translate <CR><NL> into <NL> */
7250     if (p != NULL)
7251     {
7252 	char_u	*s, *d;
7253 
7254 	d = p;
7255 	for (s = p; *s; ++s)
7256 	{
7257 	    if (s[0] == CAR && s[1] == NL)
7258 		++s;
7259 	    *d++ = *s;
7260 	}
7261 	*d = NUL;
7262     }
7263 # endif
7264 #endif
7265     retvar->var_type = VAR_STRING;
7266     retvar->var_val.var_string = p;
7267 }
7268 
7269 /*
7270  * "submatch()" function
7271  */
7272     static void
7273 f_submatch(argvars, retvar)
7274     VAR		argvars;
7275     VAR		retvar;
7276 {
7277     retvar->var_type = VAR_STRING;
7278     retvar->var_val.var_string = reg_submatch((int)get_var_number(&argvars[0]));
7279 }
7280 
7281 /*
7282  * "substitute()" function
7283  */
7284     static void
7285 f_substitute(argvars, retvar)
7286     VAR		argvars;
7287     VAR		retvar;
7288 {
7289     char_u	patbuf[NUMBUFLEN];
7290     char_u	subbuf[NUMBUFLEN];
7291     char_u	flagsbuf[NUMBUFLEN];
7292 
7293     retvar->var_type = VAR_STRING;
7294     retvar->var_val.var_string = do_string_sub(
7295 	    get_var_string(&argvars[0]),
7296 	    get_var_string_buf(&argvars[1], patbuf),
7297 	    get_var_string_buf(&argvars[2], subbuf),
7298 	    get_var_string_buf(&argvars[3], flagsbuf));
7299 }
7300 
7301 /*
7302  * "tempname()" function
7303  */
7304 /*ARGSUSED*/
7305     static void
7306 f_tempname(argvars, retvar)
7307     VAR		argvars;
7308     VAR		retvar;
7309 {
7310     static int	x = 'A';
7311 
7312     retvar->var_type = VAR_STRING;
7313     retvar->var_val.var_string = vim_tempname(x);
7314 
7315     /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different
7316      * names.  Skip 'I' and 'O', they are used for shell redirection. */
7317     do
7318     {
7319 	if (x == 'Z')
7320 	    x = '0';
7321 	else if (x == '9')
7322 	    x = 'A';
7323 	else
7324 	{
7325 #ifdef EBCDIC
7326 	    if (x == 'I')
7327 		x = 'J';
7328 	    else if (x == 'R')
7329 		x = 'S';
7330 	    else
7331 #endif
7332 		++x;
7333 	}
7334     } while (x == 'I' || x == 'O');
7335 }
7336 
7337 /*
7338  * "tolower(string)" function
7339  */
7340     static void
7341 f_tolower(argvars, retvar)
7342     VAR		argvars;
7343     VAR		retvar;
7344 {
7345     char_u	*p;
7346 
7347     p = vim_strsave(get_var_string(&argvars[0]));
7348     retvar->var_type = VAR_STRING;
7349     retvar->var_val.var_string = p;
7350 
7351     if (p != NULL)
7352 	while (*p != NUL)
7353 	{
7354 #ifdef FEAT_MBYTE
7355 	    int		l;
7356 
7357 	    if (enc_utf8)
7358 	    {
7359 		int c, lc;
7360 
7361 		c = utf_ptr2char(p);
7362 		lc = utf_tolower(c);
7363 		l = utf_ptr2len_check(p);
7364 		/* TODO: reallocate string when byte count changes. */
7365 		if (utf_char2len(lc) == l)
7366 		    utf_char2bytes(lc, p);
7367 		p += l;
7368 	    }
7369 	    else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
7370 		p += l;		/* skip multi-byte character */
7371 	    else
7372 #endif
7373 	    {
7374 		*p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
7375 		++p;
7376 	    }
7377 	}
7378 }
7379 
7380 /*
7381  * "toupper(string)" function
7382  */
7383     static void
7384 f_toupper(argvars, retvar)
7385     VAR		argvars;
7386     VAR		retvar;
7387 {
7388     char_u	*p;
7389 
7390     p = vim_strsave(get_var_string(&argvars[0]));
7391     retvar->var_type = VAR_STRING;
7392     retvar->var_val.var_string = p;
7393 
7394     if (p != NULL)
7395 	while (*p != NUL)
7396 	{
7397 #ifdef FEAT_MBYTE
7398 	    int		l;
7399 
7400 	    if (enc_utf8)
7401 	    {
7402 		int c, uc;
7403 
7404 		c = utf_ptr2char(p);
7405 		uc = utf_toupper(c);
7406 		l = utf_ptr2len_check(p);
7407 		/* TODO: reallocate string when byte count changes. */
7408 		if (utf_char2len(uc) == l)
7409 		    utf_char2bytes(uc, p);
7410 		p += l;
7411 	    }
7412 	    else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1)
7413 		p += l;		/* skip multi-byte character */
7414 	    else
7415 #endif
7416 	    {
7417 		*p = TOUPPER_LOC(*p); /* note that toupper() can be a macro */
7418 		p++;
7419 	    }
7420 	}
7421 }
7422 
7423 /*
7424  * "type(expr)" function
7425  */
7426     static void
7427 f_type(argvars, retvar)
7428     VAR		argvars;
7429     VAR		retvar;
7430 {
7431     if (argvars[0].var_type == VAR_NUMBER)
7432 	retvar->var_val.var_number = 0;
7433     else
7434 	retvar->var_val.var_number = 1;
7435 }
7436 
7437 /*
7438  * "virtcol(string)" function
7439  */
7440     static void
7441 f_virtcol(argvars, retvar)
7442     VAR		argvars;
7443     VAR		retvar;
7444 {
7445     colnr_T	vcol = 0;
7446     pos_T	*fp;
7447 
7448     fp = var2fpos(&argvars[0], FALSE);
7449     if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count)
7450     {
7451 	getvvcol(curwin, fp, NULL, NULL, &vcol);
7452 	++vcol;
7453     }
7454 
7455     retvar->var_val.var_number = vcol;
7456 }
7457 
7458 /*
7459  * "visualmode()" function
7460  */
7461 /*ARGSUSED*/
7462     static void
7463 f_visualmode(argvars, retvar)
7464     VAR		argvars;
7465     VAR		retvar;
7466 {
7467 #ifdef FEAT_VISUAL
7468     char_u	str[2];
7469 
7470     retvar->var_type = VAR_STRING;
7471     str[0] = curbuf->b_visual_mode_eval;
7472     str[1] = NUL;
7473     retvar->var_val.var_string = vim_strsave(str);
7474 
7475     /* A non-zero number or non-empty string argument: reset mode. */
7476     if ((argvars[0].var_type == VAR_NUMBER
7477 		&& argvars[0].var_val.var_number != 0)
7478 	    || (argvars[0].var_type == VAR_STRING
7479 		&& *get_var_string(&argvars[0]) != NUL))
7480 	curbuf->b_visual_mode_eval = NUL;
7481 #else
7482     retvar->var_val.var_number = 0; /* return anything, it won't work anyway */
7483 #endif
7484 }
7485 
7486 /*
7487  * "winbufnr(nr)" function
7488  */
7489     static void
7490 f_winbufnr(argvars, retvar)
7491     VAR		argvars;
7492     VAR		retvar;
7493 {
7494     win_T	*wp;
7495 
7496     wp = find_win_by_nr(&argvars[0]);
7497     if (wp == NULL)
7498 	retvar->var_val.var_number = -1;
7499     else
7500 	retvar->var_val.var_number = wp->w_buffer->b_fnum;
7501 }
7502 
7503 /*
7504  * "wincol()" function
7505  */
7506 /*ARGSUSED*/
7507     static void
7508 f_wincol(argvars, retvar)
7509     VAR		argvars;
7510     VAR		retvar;
7511 {
7512     validate_cursor();
7513     retvar->var_val.var_number = curwin->w_wcol + 1;
7514 }
7515 
7516 /*
7517  * "winheight(nr)" function
7518  */
7519     static void
7520 f_winheight(argvars, retvar)
7521     VAR		argvars;
7522     VAR		retvar;
7523 {
7524     win_T	*wp;
7525 
7526     wp = find_win_by_nr(&argvars[0]);
7527     if (wp == NULL)
7528 	retvar->var_val.var_number = -1;
7529     else
7530 	retvar->var_val.var_number = wp->w_height;
7531 }
7532 
7533 /*
7534  * "winline()" function
7535  */
7536 /*ARGSUSED*/
7537     static void
7538 f_winline(argvars, retvar)
7539     VAR		argvars;
7540     VAR		retvar;
7541 {
7542     validate_cursor();
7543     retvar->var_val.var_number = curwin->w_wrow + 1;
7544 }
7545 
7546 /*
7547  * "winnr()" function
7548  */
7549 /* ARGSUSED */
7550     static void
7551 f_winnr(argvars, retvar)
7552     VAR		argvars;
7553     VAR		retvar;
7554 {
7555     int		nr = 1;
7556 #ifdef FEAT_WINDOWS
7557     win_T	*wp;
7558 
7559     for (wp = firstwin; wp != curwin; wp = wp->w_next)
7560 	++nr;
7561 #endif
7562     retvar->var_val.var_number = nr;
7563 }
7564 
7565 /*
7566  * "winrestcmd()" function
7567  */
7568 /* ARGSUSED */
7569     static void
7570 f_winrestcmd(argvars, retvar)
7571     VAR		argvars;
7572     VAR		retvar;
7573 {
7574 #ifdef FEAT_WINDOWS
7575     win_T	*wp;
7576     int		winnr = 1;
7577     garray_T	ga;
7578     char_u	buf[50];
7579 
7580     ga_init2(&ga, (int)sizeof(char), 70);
7581     for (wp = firstwin; wp != NULL; wp = wp->w_next)
7582     {
7583 	sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height);
7584 	ga_concat(&ga, buf);
7585 # ifdef FEAT_VERTSPLIT
7586 	sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width);
7587 	ga_concat(&ga, buf);
7588 # endif
7589 	++winnr;
7590     }
7591 
7592     retvar->var_val.var_string = ga.ga_data;
7593 #else
7594     retvar->var_val.var_string = NULL;
7595 #endif
7596     retvar->var_type = VAR_STRING;
7597 }
7598 
7599 /*
7600  * "winwidth(nr)" function
7601  */
7602     static void
7603 f_winwidth(argvars, retvar)
7604     VAR		argvars;
7605     VAR		retvar;
7606 {
7607     win_T	*wp;
7608 
7609     wp = find_win_by_nr(&argvars[0]);
7610     if (wp == NULL)
7611 	retvar->var_val.var_number = -1;
7612     else
7613 #ifdef FEAT_VERTSPLIT
7614 	retvar->var_val.var_number = wp->w_width;
7615 #else
7616 	retvar->var_val.var_number = Columns;
7617 #endif
7618 }
7619 
7620     static win_T *
7621 find_win_by_nr(vp)
7622     VAR		vp;
7623 {
7624 #ifdef FEAT_WINDOWS
7625     win_T	*wp;
7626 #endif
7627     int		nr;
7628 
7629     nr = get_var_number(vp);
7630 
7631 #ifdef FEAT_WINDOWS
7632     if (nr == 0)
7633 	return curwin;
7634 
7635     for (wp = firstwin; wp != NULL; wp = wp->w_next)
7636 	if (--nr <= 0)
7637 	    break;
7638     return wp;
7639 #else
7640     if (nr == 0 || nr == 1)
7641 	return curwin;
7642     return NULL;
7643 #endif
7644 }
7645 
7646 /*
7647  * Translate a String variable into a position.
7648  */
7649     static pos_T *
7650 var2fpos(varp, lnum)
7651     VAR		varp;
7652     int		lnum;		/* TRUE when $ is last line */
7653 {
7654     char_u	*name;
7655     static pos_T	pos;
7656     pos_T	*pp;
7657 
7658     name = get_var_string(varp);
7659     if (name[0] == '.')		/* cursor */
7660 	return &curwin->w_cursor;
7661     if (name[0] == '\'')	/* mark */
7662     {
7663 	pp = getmark(name[1], FALSE);
7664 	if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
7665 	    return NULL;
7666 	return pp;
7667     }
7668     if (name[0] == '$')		/* last column or line */
7669     {
7670 	if (lnum)
7671 	{
7672 	    pos.lnum = curbuf->b_ml.ml_line_count;
7673 	    pos.col = 0;
7674 	}
7675 	else
7676 	{
7677 	    pos.lnum = curwin->w_cursor.lnum;
7678 	    pos.col = (colnr_T)STRLEN(ml_get_curline());
7679 	}
7680 	return &pos;
7681     }
7682     return NULL;
7683 }
7684 
7685 /*
7686  * Get the length of an environment variable name.
7687  * Advance "arg" to the first character after the name.
7688  * Return 0 for error.
7689  */
7690     static int
7691 get_env_len(arg)
7692     char_u	**arg;
7693 {
7694     char_u	*p;
7695     int		len;
7696 
7697     for (p = *arg; vim_isIDc(*p); ++p)
7698 	;
7699     if (p == *arg)	    /* no name found */
7700 	return 0;
7701 
7702     len = (int)(p - *arg);
7703     *arg = p;
7704     return len;
7705 }
7706 
7707 /*
7708  * Get the length of the name of a function or internal variable.
7709  * "arg" is advanced to the first non-white character after the name.
7710  * Return 0 if something is wrong.
7711  */
7712     static int
7713 get_id_len(arg)
7714     char_u	**arg;
7715 {
7716     char_u	*p;
7717     int		len;
7718 
7719     /* Find the end of the name. */
7720     for (p = *arg; eval_isnamec(*p); ++p)
7721 	;
7722     if (p == *arg)	    /* no name found */
7723 	return 0;
7724 
7725     len = (int)(p - *arg);
7726     *arg = skipwhite(p);
7727 
7728     return len;
7729 }
7730 
7731 /*
7732  * Get the length of the name of a function.
7733  * "arg" is advanced to the first non-white character after the name.
7734  * Return 0 if something is wrong.
7735  * If the name contains 'magic' {}'s, expand them and return the
7736  * expanded name in an allocated string via 'alias' - caller must free.
7737  */
7738     static int
7739 get_func_len(arg, alias, evaluate)
7740     char_u	**arg;
7741     char_u	**alias;
7742     int		evaluate;
7743 {
7744     int		len;
7745 #ifdef FEAT_MAGIC_BRACES
7746     char_u	*p;
7747     char_u	*expr_start;
7748     char_u	*expr_end;
7749 #endif
7750 
7751     *alias = NULL;  /* default to no alias */
7752 
7753     if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
7754 						  && (*arg)[2] == (int)KE_SNR)
7755     {
7756 	/* hard coded <SNR>, already translated */
7757 	*arg += 3;
7758 	return get_id_len(arg) + 3;
7759     }
7760     len = eval_fname_script(*arg);
7761     if (len > 0)
7762     {
7763 	/* literal "<SID>", "s:" or "<SNR>" */
7764 	*arg += len;
7765     }
7766 
7767 #ifdef FEAT_MAGIC_BRACES
7768     /*
7769      * Find the end of the name;
7770      */
7771     p = find_name_end(*arg, &expr_start, &expr_end);
7772     /* check for {} construction */
7773     if (expr_start != NULL)
7774     {
7775 	char_u	*temp_string;
7776 
7777 	if (!evaluate)
7778 	{
7779 	    len += (int)(p - *arg);
7780 	    *arg = skipwhite(p);
7781 	    return len;
7782 	}
7783 
7784 	/*
7785 	 * Include any <SID> etc in the expanded string:
7786 	 * Thus the -len here.
7787 	 */
7788 	temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
7789 	if (temp_string == NULL)
7790 	    return 0;
7791 	*alias = temp_string;
7792 	*arg = skipwhite(p);
7793 	return (int)STRLEN(temp_string);
7794     }
7795 #endif
7796 
7797     len += get_id_len(arg);
7798     if (len == 0)
7799 	EMSG2(_(e_invexpr2), *arg);
7800 
7801     return len;
7802 }
7803 
7804     static char_u *
7805 find_name_end(arg, expr_start, expr_end)
7806     char_u	*arg;
7807     char_u	**expr_start;
7808     char_u	**expr_end;
7809 {
7810     int		nesting = 0;
7811     char_u	*p;
7812 
7813     *expr_start = NULL;
7814     *expr_end = NULL;
7815 
7816     for (p = arg; (*p != NUL && (eval_isnamec(*p) || nesting != 0)); ++p)
7817     {
7818 #ifdef FEAT_MAGIC_BRACES
7819 	if (*p == '{')
7820 	{
7821 	    nesting++;
7822 	    if (*expr_start == NULL)
7823 		*expr_start = p;
7824 	}
7825 	else if (*p == '}')
7826 	{
7827 	    nesting--;
7828 	    if (nesting == 0 && *expr_end == NULL)
7829 		*expr_end = p;
7830 	}
7831 #endif
7832     }
7833 
7834     return p;
7835 }
7836 
7837 /*
7838  * Return TRUE if character "c" can be used in a variable or function name.
7839  */
7840     static int
7841 eval_isnamec(c)
7842     int	    c;
7843 {
7844     return (ASCII_ISALNUM(c) || c == '_' || c == ':'
7845 #ifdef FEAT_MAGIC_BRACES
7846 	    || c == '{' || c == '}'
7847 #endif
7848 	    );
7849 }
7850 
7851 /*
7852  * Find a v: variable.
7853  * Return it's index, or -1 if not found.
7854  */
7855     static int
7856 find_vim_var(name, len)
7857     char_u	*name;
7858     int		len;		/* length of "name" */
7859 {
7860     char_u	*vname;
7861     int		vlen;
7862     int		i;
7863 
7864     /*
7865      * Ignore "v:" for old built-in variables, require it for new ones.
7866      */
7867     if (name[0] == 'v' && name[1] == ':')
7868     {
7869 	vname = name + 2;
7870 	vlen = len - 2;
7871     }
7872     else
7873     {
7874 	vname = name;
7875 	vlen = len;
7876     }
7877     for (i = 0; i < VV_LEN; ++i)
7878 	if (vlen == vimvars[i].len && STRCMP(vname, vimvars[i].name) == 0
7879 			 && ((vimvars[i].flags & VV_COMPAT) || vname != name))
7880 	    return i;
7881     return -1;
7882 }
7883 
7884 /*
7885  * Set number v: variable to "val".
7886  */
7887     void
7888 set_vim_var_nr(idx, val)
7889     int		idx;
7890     long	val;
7891 {
7892     vimvars[idx].val = (char_u *)val;
7893 }
7894 
7895 /*
7896  * Get number v: variable value;
7897  */
7898     long
7899 get_vim_var_nr(idx)
7900     int		idx;
7901 {
7902     return (long)vimvars[idx].val;
7903 }
7904 
7905 /*
7906  * Set v:count, v:count1 and v:prevcount.
7907  */
7908     void
7909 set_vcount(count, count1)
7910     long	count;
7911     long	count1;
7912 {
7913     vimvars[VV_PREVCOUNT].val = vimvars[VV_COUNT].val;
7914     vimvars[VV_COUNT].val = (char_u *)count;
7915     vimvars[VV_COUNT1].val = (char_u *)count1;
7916 }
7917 
7918 /*
7919  * Set string v: variable to a copy of "val".
7920  */
7921     void
7922 set_vim_var_string(idx, val, len)
7923     int		idx;
7924     char_u	*val;
7925     int		len;	    /* length of "val" to use or -1 (whole string) */
7926 {
7927     vim_free(vimvars[idx].val);
7928     if (val == NULL)
7929 	vimvars[idx].val = NULL;
7930     else if (len == -1)
7931 	vimvars[idx].val = vim_strsave(val);
7932     else
7933 	vimvars[idx].val = vim_strnsave(val, len);
7934 }
7935 
7936 /*
7937  * Set v:register if needed.
7938  */
7939     void
7940 set_reg_var(c)
7941     int		c;
7942 {
7943     char_u	regname;
7944 
7945     if (c == 0 || c == ' ')
7946 	regname = '"';
7947     else
7948 	regname = c;
7949     /* Avoid free/alloc when the value is already right. */
7950     if (vimvars[VV_REG].val == NULL || vimvars[VV_REG].val[0] != c)
7951 	set_vim_var_string(VV_REG, &regname, 1);
7952 }
7953 
7954 /*
7955  * Get or set v:exception.  If "oldval" == NULL, return the current value.
7956  * Otherwise, restore the value to "oldval" and return NULL.
7957  * Must always be called in pairs to save and restore v:exception!  Does not
7958  * take care of memory allocations.
7959  */
7960     char_u *
7961 v_exception(oldval)
7962     char_u	*oldval;
7963 {
7964     if (oldval == NULL)
7965 	return vimvars[VV_EXCEPTION].val;
7966 
7967     vimvars[VV_EXCEPTION].val = oldval;
7968     return NULL;
7969 }
7970 
7971 /*
7972  * Get or set v:throwpoint.  If "oldval" == NULL, return the current value.
7973  * Otherwise, restore the value to "oldval" and return NULL.
7974  * Must always be called in pairs to save and restore v:throwpoint!  Does not
7975  * take care of memory allocations.
7976  */
7977     char_u *
7978 v_throwpoint(oldval)
7979     char_u	*oldval;
7980 {
7981     if (oldval == NULL)
7982 	return vimvars[VV_THROWPOINT].val;
7983 
7984     vimvars[VV_THROWPOINT].val = oldval;
7985     return NULL;
7986 }
7987 
7988 #if defined(FEAT_AUTOCMD) || defined(PROTO)
7989 /*
7990  * Set v:cmdarg.
7991  * If "eap" != NULL, use "eap" to generate the value and return the old value.
7992  * If "oldarg" != NULL, restore the value to "oldarg" and return NULL.
7993  * Must always be called in pairs!
7994  */
7995     char_u *
7996 set_cmdarg(eap, oldarg)
7997     exarg_T	*eap;
7998     char_u	*oldarg;
7999 {
8000     char_u	*oldval;
8001     char_u	*newval;
8002     unsigned	len;
8003 
8004     oldval = vimvars[VV_CMDARG].val;
8005     if (eap != NULL)
8006     {
8007 	if (eap->force_bin == FORCE_BIN)
8008 	    len = 6;
8009 	else if (eap->force_bin == FORCE_NOBIN)
8010 	    len = 8;
8011 	else
8012 	    len = 0;
8013 	if (eap->force_ff != 0)
8014 	    len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6;
8015 # ifdef FEAT_MBYTE
8016 	if (eap->force_enc != 0)
8017 	    len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7;
8018 # endif
8019 
8020 	newval = alloc(len + 1);
8021 	if (newval == NULL)
8022 	    return NULL;
8023 
8024 	if (eap->force_bin == FORCE_BIN)
8025 	    sprintf((char *)newval, " ++bin");
8026 	else if (eap->force_bin == FORCE_NOBIN)
8027 	    sprintf((char *)newval, " ++nobin");
8028 	else
8029 	    *newval = NUL;
8030 	if (eap->force_ff != 0)
8031 	    sprintf((char *)newval + STRLEN(newval), " ++ff=%s",
8032 						    eap->cmd + eap->force_ff);
8033 # ifdef FEAT_MBYTE
8034 	if (eap->force_enc != 0)
8035 	    sprintf((char *)newval + STRLEN(newval), " ++enc=%s",
8036 						   eap->cmd + eap->force_enc);
8037 # endif
8038 	vimvars[VV_CMDARG].val = newval;
8039 	return oldval;
8040     }
8041 
8042     vim_free(oldval);
8043     vimvars[VV_CMDARG].val = oldarg;
8044     return NULL;
8045 }
8046 #endif
8047 
8048 /*
8049  * Get the value of internal variable "name".
8050  * Return OK or FAIL.
8051  */
8052     static int
8053 get_var_var(name, len, retvar)
8054     char_u	*name;
8055     int		len;		/* length of "name" */
8056     VAR		retvar;		/* NULL when only checking existence */
8057 {
8058     int		ret = OK;
8059     int		type = VAR_UNKNOWN;
8060     long	number = 1;
8061     char_u	*string = NULL;
8062     VAR		v;
8063     int		cc;
8064     int		i;
8065 
8066     /* truncate the name, so that we can use strcmp() */
8067     cc = name[len];
8068     name[len] = NUL;
8069 
8070     /*
8071      * Check for "b:changedtick".
8072      */
8073     if (STRCMP(name, "b:changedtick") == 0)
8074     {
8075 	type = VAR_NUMBER;
8076 	number = curbuf->b_changedtick;
8077     }
8078 
8079     /*
8080      * Check for built-in v: variables.
8081      */
8082     else if ((i = find_vim_var(name, len)) >= 0)
8083     {
8084 	type = vimvars[i].type;
8085 	number = (long)vimvars[i].val;
8086 	string = vimvars[i].val;
8087     }
8088 
8089     /*
8090      * Check for user-defined variables.
8091      */
8092     else
8093     {
8094 	v = find_var(name, FALSE);
8095 	if (v != NULL)
8096 	{
8097 	    type = v->var_type;
8098 	    number = v->var_val.var_number;
8099 	    string = v->var_val.var_string;
8100 	}
8101     }
8102 
8103     if (type == VAR_UNKNOWN)
8104     {
8105 	if (retvar != NULL)
8106 	    EMSG2(_("E121: Undefined variable: %s"), name);
8107 	ret = FAIL;
8108     }
8109     else if (retvar != NULL)
8110     {
8111 	retvar->var_type = type;
8112 	if (type == VAR_NUMBER)
8113 	    retvar->var_val.var_number = number;
8114 	else if (type == VAR_STRING)
8115 	{
8116 	    if (string != NULL)
8117 		string = vim_strsave(string);
8118 	    retvar->var_val.var_string = string;
8119 	}
8120     }
8121 
8122     name[len] = cc;
8123 
8124     return ret;
8125 }
8126 
8127 /*
8128  * Allocate memory for a variable, and make it emtpy (0 or NULL value).
8129  */
8130     static VAR
8131 alloc_var()
8132 {
8133     return (VAR)alloc_clear((unsigned)sizeof(var));
8134 }
8135 
8136 /*
8137  * Allocate memory for a variable, and assign a string to it.
8138  * The string "s" must have been allocated, it is consumed.
8139  * Return NULL for out of memory, the variable otherwise.
8140  */
8141     static VAR
8142 alloc_string_var(s)
8143     char_u	*s;
8144 {
8145     VAR	    retvar;
8146 
8147     retvar = alloc_var();
8148     if (retvar != NULL)
8149     {
8150 	retvar->var_type = VAR_STRING;
8151 	retvar->var_val.var_string = s;
8152     }
8153     else
8154 	vim_free(s);
8155     return retvar;
8156 }
8157 
8158 /*
8159  * Free the memory for a variable.
8160  */
8161     static void
8162 free_var(varp)
8163     VAR	    varp;
8164 {
8165     if (varp != NULL)
8166     {
8167 	if (varp->var_type == VAR_STRING)
8168 	    vim_free(varp->var_val.var_string);
8169 	vim_free(varp->var_name);
8170 	vim_free(varp);
8171     }
8172 }
8173 
8174 /*
8175  * Free the memory for a variable value and set the value to NULL or 0.
8176  */
8177     static void
8178 clear_var(varp)
8179     VAR	    varp;
8180 {
8181     if (varp != NULL)
8182     {
8183 	if (varp->var_type == VAR_STRING)
8184 	{
8185 	    vim_free(varp->var_val.var_string);
8186 	    varp->var_val.var_string = NULL;
8187 	}
8188 	else
8189 	    varp->var_val.var_number = 0;
8190     }
8191 }
8192 
8193 /*
8194  * Get the number value of a variable.
8195  * If it is a String variable, uses vim_str2nr().
8196  */
8197     static long
8198 get_var_number(varp)
8199     VAR		varp;
8200 {
8201     long	n;
8202 
8203     if (varp->var_type == VAR_NUMBER)
8204 	return (long)(varp->var_val.var_number);
8205     else if (varp->var_type == VAR_UNKNOWN || varp->var_val.var_string == NULL)
8206 	return 0L;
8207     else
8208     {
8209 	vim_str2nr(varp->var_val.var_string, NULL, NULL, TRUE, TRUE, &n, NULL);
8210 	return n;
8211     }
8212 }
8213 
8214 /*
8215  * Get the lnum from the first argument.  Also accepts ".", "$", etc.
8216  */
8217     static linenr_T
8218 get_var_lnum(argvars)
8219     VAR		argvars;
8220 {
8221     var		retvar;
8222     linenr_T	lnum;
8223 
8224     lnum = get_var_number(&argvars[0]);
8225     if (lnum == 0)  /* no valid number, try using line() */
8226     {
8227 	retvar.var_type = VAR_NUMBER;
8228 	f_line(argvars, &retvar);
8229 	lnum = retvar.var_val.var_number;
8230 	clear_var(&retvar);
8231     }
8232     return lnum;
8233 }
8234 
8235 /*
8236  * Get the string value of a variable.
8237  * If it is a Number variable, the number is converted into a string.
8238  * get_var_string() uses a single, static buffer.  YOU CAN ONLY USE IT ONCE!
8239  * get_var_string_buf() uses a given buffer.
8240  * If the String variable has never been set, return an empty string.
8241  * Never returns NULL;
8242  */
8243     static char_u *
8244 get_var_string(varp)
8245     VAR	    varp;
8246 {
8247     static char_u   mybuf[NUMBUFLEN];
8248 
8249     return get_var_string_buf(varp, mybuf);
8250 }
8251 
8252     static char_u *
8253 get_var_string_buf(varp, buf)
8254     VAR	    varp;
8255     char_u  *buf;
8256 {
8257     if (varp->var_type == VAR_NUMBER)
8258     {
8259 	sprintf((char *)buf, "%ld", (long)varp->var_val.var_number);
8260 	return buf;
8261     }
8262     else if (varp->var_val.var_string == NULL)
8263 	return (char_u *)"";
8264     else
8265 	return varp->var_val.var_string;
8266 }
8267 
8268 /*
8269  * Find variable "name" in the list of variables.
8270  * Return a pointer to it if found, NULL if not found.
8271  */
8272     static VAR
8273 find_var(name, writing)
8274     char_u	*name;
8275     int		writing;
8276 {
8277     int		i;
8278     char_u	*varname;
8279     garray_T	*gap;
8280 
8281     /* Check for function arguments "a:" */
8282     if (name[0] == 'a' && name[1] == ':')
8283     {
8284 	if (writing)
8285 	{
8286 	    EMSG2(_(e_readonlyvar), name);
8287 	    return NULL;
8288 	}
8289 	name += 2;
8290 	if (current_funccal == NULL)
8291 	    return NULL;
8292 	if (VIM_ISDIGIT(*name))
8293 	{
8294 	    i = atol((char *)name);
8295 	    if (i == 0)					/* a:0 */
8296 		return &current_funccal->a0_var;
8297 	    i += current_funccal->func->args.ga_len;
8298 	    if (i > current_funccal->argcount)		/* a:999 */
8299 		return NULL;
8300 	    return &(current_funccal->argvars[i - 1]);	/* a:1, a:2, etc. */
8301 	}
8302 	if (STRCMP(name, "firstline") == 0)
8303 	    return &(current_funccal->firstline);
8304 	if (STRCMP(name, "lastline") == 0)
8305 	    return &(current_funccal->lastline);
8306 	for (i = 0; i < current_funccal->func->args.ga_len; ++i)
8307 	    if (STRCMP(name, ((char_u **)
8308 			      (current_funccal->func->args.ga_data))[i]) == 0)
8309 	    return &(current_funccal->argvars[i]);	/* a:name */
8310 	return NULL;
8311     }
8312 
8313     gap = find_var_ga(name, &varname);
8314     if (gap == NULL)
8315 	return NULL;
8316     return find_var_in_ga(gap, varname);
8317 }
8318 
8319     static VAR
8320 find_var_in_ga(gap, varname)
8321     garray_T	*gap;
8322     char_u	*varname;
8323 {
8324     int	i;
8325 
8326     for (i = gap->ga_len; --i >= 0; )
8327 	if (VAR_GAP_ENTRY(i, gap).var_name != NULL
8328 		&& STRCMP(VAR_GAP_ENTRY(i, gap).var_name, varname) == 0)
8329 	    break;
8330     if (i < 0)
8331 	return NULL;
8332     return &VAR_GAP_ENTRY(i, gap);
8333 }
8334 
8335 /*
8336  * Find the growarray and start of name without ':' for a variable name.
8337  */
8338     static garray_T *
8339 find_var_ga(name, varname)
8340     char_u  *name;
8341     char_u  **varname;
8342 {
8343     if (name[1] != ':')
8344     {
8345 	/* If not "x:name" there must not be any ":" in the name. */
8346 	if (vim_strchr(name, ':') != NULL)
8347 	    return NULL;
8348 	*varname = name;
8349 	if (current_funccal == NULL)
8350 	    return &variables;			/* global variable */
8351 	return &current_funccal->l_vars;	/* local function variable */
8352     }
8353     *varname = name + 2;
8354     if (*name == 'b')				/* buffer variable */
8355 	return &curbuf->b_vars;
8356     if (*name == 'w')				/* window variable */
8357 	return &curwin->w_vars;
8358     if (*name == 'g')				/* global variable */
8359 	return &variables;
8360     if (*name == 'l' && current_funccal != NULL)/* local function variable */
8361 	return &current_funccal->l_vars;
8362     if (*name == 's'				/* script variable */
8363 	    && current_SID > 0 && current_SID <= ga_scripts.ga_len)
8364 	return &SCRIPT_VARS(current_SID);
8365     return NULL;
8366 }
8367 
8368 /*
8369  * Get the string value of a (global/local) variable.
8370  * Returns NULL when it doesn't exist.
8371  */
8372     char_u *
8373 get_var_value(name)
8374     char_u	*name;
8375 {
8376     VAR		v;
8377 
8378     v = find_var(name, FALSE);
8379     if (v == NULL)
8380 	return NULL;
8381     return get_var_string(v);
8382 }
8383 
8384 /*
8385  * Allocate a new growarry for a sourced script.  It will be used while
8386  * sourcing this script and when executing functions defined in the script.
8387  */
8388     void
8389 new_script_vars(id)
8390     scid_T id;
8391 {
8392     if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK)
8393     {
8394 	while (ga_scripts.ga_len < id)
8395 	{
8396 	    var_init(&SCRIPT_VARS(ga_scripts.ga_len + 1));
8397 	    ++ga_scripts.ga_len;
8398 	    --ga_scripts.ga_room;
8399 	}
8400     }
8401 }
8402 
8403 /*
8404  * Initialize internal variables for use.
8405  */
8406     void
8407 var_init(gap)
8408     garray_T *gap;
8409 {
8410     ga_init2(gap, (int)sizeof(var), 4);
8411 }
8412 
8413 /*
8414  * Clean up a list of internal variables.
8415  */
8416     void
8417 var_clear(gap)
8418     garray_T *gap;
8419 {
8420     int	    i;
8421 
8422     for (i = gap->ga_len; --i >= 0; )
8423 	var_free_one(&VAR_GAP_ENTRY(i, gap));
8424     ga_clear(gap);
8425 }
8426 
8427     static void
8428 var_free_one(v)
8429     VAR	    v;
8430 {
8431     vim_free(v->var_name);
8432     v->var_name = NULL;
8433     if (v->var_type == VAR_STRING)
8434 	vim_free(v->var_val.var_string);
8435     v->var_val.var_string = NULL;
8436 }
8437 
8438 /*
8439  * List the value of one internal variable.
8440  */
8441     static void
8442 list_one_var(v, prefix)
8443     VAR		v;
8444     char_u	*prefix;
8445 {
8446     list_one_var_a(prefix, v->var_name, v->var_type, get_var_string(v));
8447 }
8448 
8449 /*
8450  * List the value of one "v:" variable.
8451  */
8452     static void
8453 list_vim_var(i)
8454     int		i;	/* index in vimvars[] */
8455 {
8456     char_u	*p;
8457     char_u	numbuf[NUMBUFLEN];
8458 
8459     if (vimvars[i].type == VAR_NUMBER)
8460     {
8461 	p = numbuf;
8462 	sprintf((char *)p, "%ld", (long)vimvars[i].val);
8463     }
8464     else if (vimvars[i].val == NULL)
8465 	p = (char_u *)"";
8466     else
8467 	p = vimvars[i].val;
8468     list_one_var_a((char_u *)"v:", (char_u *)vimvars[i].name,
8469 							  vimvars[i].type, p);
8470 }
8471 
8472     static void
8473 list_one_var_a(prefix, name, type, string)
8474     char_u	*prefix;
8475     char_u	*name;
8476     int		type;
8477     char_u	*string;
8478 {
8479     msg_attr(prefix, 0);    /* don't use msg(), it overwrites "v:statusmsg" */
8480     if (name != NULL)	/* "a:" vars don't have a name stored */
8481 	msg_puts(name);
8482     msg_putchar(' ');
8483     msg_advance(22);
8484     if (type == VAR_NUMBER)
8485 	msg_putchar('#');
8486     else
8487 	msg_putchar(' ');
8488     msg_outtrans(string);
8489 }
8490 
8491 /*
8492  * Set variable "name" to value in "varp".
8493  * If the variable already exists, the value is updated.
8494  * Otherwise the variable is created.
8495  */
8496     static void
8497 set_var(name, varp)
8498     char_u	*name;
8499     VAR		varp;
8500 {
8501     int		i;
8502     VAR		v;
8503     char_u	*varname;
8504     garray_T	*gap;
8505 
8506     /*
8507      * Handle setting internal v: variables.
8508      */
8509     i = find_vim_var(name, (int)STRLEN(name));
8510     if (i >= 0)
8511     {
8512 	if (vimvars[i].flags & VV_RO)
8513 	    EMSG2(_(e_readonlyvar), name);
8514 	else
8515 	{
8516 	    if (vimvars[i].type == VAR_STRING)
8517 	    {
8518 		vim_free(vimvars[i].val);
8519 		vimvars[i].val = vim_strsave(get_var_string(varp));
8520 	    }
8521 	    else
8522 		vimvars[i].val = (char_u *)(long)varp->var_val.var_number;
8523 	}
8524 	return;
8525     }
8526 
8527     v = find_var(name, TRUE);
8528     if (v != NULL)	    /* existing variable, only need to free string */
8529     {
8530 	if (v->var_type == VAR_STRING)
8531 	    vim_free(v->var_val.var_string);
8532     }
8533     else		    /* add a new variable */
8534     {
8535 	gap = find_var_ga(name, &varname);
8536 	if (gap == NULL)    /* illegal name */
8537 	{
8538 	    EMSG2(_("E461: Illegal variable name: %s"), name);
8539 	    return;
8540 	}
8541 
8542 	/* Try to use an empty entry */
8543 	for (i = gap->ga_len; --i >= 0; )
8544 	    if (VAR_GAP_ENTRY(i, gap).var_name == NULL)
8545 		break;
8546 	if (i < 0)	    /* need to allocate more room */
8547 	{
8548 	    if (ga_grow(gap, 1) == FAIL)
8549 		return;
8550 	    i = gap->ga_len;
8551 	}
8552 	v = &VAR_GAP_ENTRY(i, gap);
8553 	if ((v->var_name = vim_strsave(varname)) == NULL)
8554 	    return;
8555 	if (i == gap->ga_len)
8556 	{
8557 	    ++gap->ga_len;
8558 	    --gap->ga_room;
8559 	}
8560     }
8561     copy_var(varp, v);
8562 }
8563 
8564     static void
8565 copy_var(from, to)
8566     VAR	from;
8567     VAR	to;
8568 {
8569     to->var_type = from->var_type;
8570     if (from->var_type == VAR_STRING)
8571 	to->var_val.var_string = vim_strsave(get_var_string(from));
8572     else
8573 	to->var_val.var_number = from->var_val.var_number;
8574 }
8575 
8576 /*
8577  * ":echo expr1 ..."	print each argument separated with a space, add a
8578  *			newline at the end.
8579  * ":echon expr1 ..."	print each argument plain.
8580  */
8581     void
8582 ex_echo(eap)
8583     exarg_T	*eap;
8584 {
8585     char_u	*arg = eap->arg;
8586     var		retvar;
8587     char_u	*p;
8588     int		needclr = TRUE;
8589     int		atstart = TRUE;
8590 
8591     if (eap->skip)
8592 	++emsg_skip;
8593     while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int)
8594     {
8595 	p = arg;
8596 	if (eval1(&arg, &retvar, !eap->skip) == FAIL)
8597 	{
8598 	    /*
8599 	     * Report the invalid expression unless the expression evaluation
8600 	     * has been cancelled due to an aborting error, an interrupt, or an
8601 	     * exception.
8602 	     */
8603 	    if (!aborting())
8604 		EMSG2(_(e_invexpr2), p);
8605 	    break;
8606 	}
8607 	if (!eap->skip)
8608 	{
8609 	    if (atstart)
8610 	    {
8611 		atstart = FALSE;
8612 		/* Call msg_start() after eval1(), evaluating the expression
8613 		 * may cause a message to appear. */
8614 		if (eap->cmdidx == CMD_echo)
8615 		    msg_start();
8616 	    }
8617 	    else if (eap->cmdidx == CMD_echo)
8618 		msg_puts_attr((char_u *)" ", echo_attr);
8619 	    for (p = get_var_string(&retvar); *p != NUL && !got_int; ++p)
8620 		if (*p == '\n' || *p == '\r' || *p == TAB)
8621 		{
8622 		    if (*p != TAB && needclr)
8623 		    {
8624 			/* remove any text still there from the command */
8625 			msg_clr_eos();
8626 			needclr = FALSE;
8627 		    }
8628 		    msg_putchar_attr(*p, echo_attr);
8629 		}
8630 		else
8631 		{
8632 #ifdef FEAT_MBYTE
8633 		    if (has_mbyte)
8634 		    {
8635 			int i = (*mb_ptr2len_check)(p);
8636 
8637 			(void)msg_outtrans_len_attr(p, i, echo_attr);
8638 			p += i - 1;
8639 		    }
8640 		    else
8641 #endif
8642 			(void)msg_outtrans_len_attr(p, 1, echo_attr);
8643 		}
8644 	}
8645 	clear_var(&retvar);
8646 	arg = skipwhite(arg);
8647     }
8648     eap->nextcmd = check_nextcmd(arg);
8649 
8650     if (eap->skip)
8651 	--emsg_skip;
8652     else
8653     {
8654 	/* remove text that may still be there from the command */
8655 	if (needclr)
8656 	    msg_clr_eos();
8657 	if (eap->cmdidx == CMD_echo)
8658 	    msg_end();
8659     }
8660 }
8661 
8662 /*
8663  * ":echohl {name}".
8664  */
8665     void
8666 ex_echohl(eap)
8667     exarg_T	*eap;
8668 {
8669     int		id;
8670 
8671     id = syn_name2id(eap->arg);
8672     if (id == 0)
8673 	echo_attr = 0;
8674     else
8675 	echo_attr = syn_id2attr(id);
8676 }
8677 
8678 /*
8679  * ":execute expr1 ..."	execute the result of an expression.
8680  * ":echomsg expr1 ..."	Print a message
8681  * ":echoerr expr1 ..."	Print an error
8682  * Each gets spaces around each argument and a newline at the end for
8683  * echo commands
8684  */
8685     void
8686 ex_execute(eap)
8687     exarg_T	*eap;
8688 {
8689     char_u	*arg = eap->arg;
8690     var		retvar;
8691     int		ret = OK;
8692     char_u	*p;
8693     garray_T	ga;
8694     int		len;
8695     int		save_did_emsg;
8696 
8697     ga_init2(&ga, 1, 80);
8698 
8699     if (eap->skip)
8700 	++emsg_skip;
8701     while (*arg != NUL && *arg != '|' && *arg != '\n')
8702     {
8703 	p = arg;
8704 	if (eval1(&arg, &retvar, !eap->skip) == FAIL)
8705 	{
8706 	    /*
8707 	     * Report the invalid expression unless the expression evaluation
8708 	     * has been cancelled due to an aborting error, an interrupt, or an
8709 	     * exception.
8710 	     */
8711 	    if (!aborting())
8712 		EMSG2(_(e_invexpr2), p);
8713 	    ret = FAIL;
8714 	    break;
8715 	}
8716 
8717 	if (!eap->skip)
8718 	{
8719 	    p = get_var_string(&retvar);
8720 	    len = (int)STRLEN(p);
8721 	    if (ga_grow(&ga, len + 2) == FAIL)
8722 	    {
8723 		clear_var(&retvar);
8724 		ret = FAIL;
8725 		break;
8726 	    }
8727 	    if (ga.ga_len)
8728 	    {
8729 		((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
8730 		--ga.ga_room;
8731 	    }
8732 	    STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
8733 	    ga.ga_room -= len;
8734 	    ga.ga_len += len;
8735 	}
8736 
8737 	clear_var(&retvar);
8738 	arg = skipwhite(arg);
8739     }
8740 
8741     if (ret != FAIL && ga.ga_data != NULL)
8742     {
8743 	if (eap->cmdidx == CMD_echomsg)
8744 	    MSG_ATTR(ga.ga_data, echo_attr);
8745 	else if (eap->cmdidx == CMD_echoerr)
8746 	{
8747 	    /* We don't want to abort following commands, restore did_emsg. */
8748 	    save_did_emsg = did_emsg;
8749 	    EMSG((char_u *)ga.ga_data);
8750 	    if (!force_abort)
8751 		did_emsg = save_did_emsg;
8752 	}
8753 	else if (eap->cmdidx == CMD_execute)
8754 	    do_cmdline((char_u *)ga.ga_data,
8755 		       eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
8756     }
8757 
8758     ga_clear(&ga);
8759 
8760     if (eap->skip)
8761 	--emsg_skip;
8762 
8763     eap->nextcmd = check_nextcmd(arg);
8764 }
8765 
8766 /*
8767  * Skip over the name of an option: "&option", "&g:option" or "&l:option".
8768  * "arg" points to the "&" or '+' when called, to "option" when returning.
8769  * Returns NULL when no option name found.  Otherwise pointer to the char
8770  * after the option name.
8771  */
8772     static char_u *
8773 find_option_end(arg, opt_flags)
8774     char_u	**arg;
8775     int		*opt_flags;
8776 {
8777     char_u	*p = *arg;
8778 
8779     ++p;
8780     if (*p == 'g' && p[1] == ':')
8781     {
8782 	*opt_flags = OPT_GLOBAL;
8783 	p += 2;
8784     }
8785     else if (*p == 'l' && p[1] == ':')
8786     {
8787 	*opt_flags = OPT_LOCAL;
8788 	p += 2;
8789     }
8790     else
8791 	*opt_flags = 0;
8792 
8793     if (!ASCII_ISALPHA(*p))
8794 	return NULL;
8795     *arg = p;
8796 
8797     if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
8798 	p += 4;	    /* termcap option */
8799     else
8800 	while (ASCII_ISALPHA(*p))
8801 	    ++p;
8802     return p;
8803 }
8804 
8805 /*
8806  * ":function"
8807  */
8808     void
8809 ex_function(eap)
8810     exarg_T	*eap;
8811 {
8812     char_u	*theline;
8813     int		j;
8814     int		c;
8815 #ifdef FEAT_MAGIC_BRACES
8816     int		saved_did_emsg;
8817 #endif
8818     char_u	*name = NULL;
8819     char_u	*p;
8820     char_u	*arg;
8821     garray_T	newargs;
8822     garray_T	newlines;
8823     int		varargs = FALSE;
8824     int		mustend = FALSE;
8825     int		flags = 0;
8826     ufunc_T	*fp;
8827     int		indent;
8828     int		nesting;
8829     char_u	*skip_until = NULL;
8830     static char_u e_funcexts[] = N_("E122: Function %s already exists, add ! to replace it");
8831 
8832     /*
8833      * ":function" without argument: list functions.
8834      */
8835     if (ends_excmd(*eap->arg))
8836     {
8837 	if (!eap->skip)
8838 	    for (fp = firstfunc; fp != NULL && !got_int; fp = fp->next)
8839 		list_func_head(fp, FALSE);
8840 	eap->nextcmd = check_nextcmd(eap->arg);
8841 	return;
8842     }
8843 
8844     p = eap->arg;
8845     name = trans_function_name(&p, eap->skip, FALSE);
8846     if (name == NULL && !eap->skip)
8847     {
8848 	/*
8849 	 * Return on an invalid expression in braces, unless the expression
8850 	 * evaluation has been cancelled due to an aborting error, an
8851 	 * interrupt, or an exception.
8852 	 */
8853 	if (!aborting())
8854 	    return;
8855 	else
8856 	    eap->skip = TRUE;
8857     }
8858 #ifdef FEAT_MAGIC_BRACES
8859     /* An error in a function call during evaluation of an expression in magic
8860      * braces should not cause the function not to be defined. */
8861     saved_did_emsg = did_emsg;
8862     did_emsg = FALSE;
8863 #endif
8864 
8865     /*
8866      * ":function func" with only function name: list function.
8867      */
8868     if (vim_strchr(p, '(') == NULL)
8869     {
8870 	if (!ends_excmd(*skipwhite(p)))
8871 	{
8872 	    EMSG(_(e_trailing));
8873 	    goto erret_name;
8874 	}
8875 	eap->nextcmd = check_nextcmd(p);
8876 	if (eap->nextcmd != NULL)
8877 	    *p = NUL;
8878 	if (!eap->skip && !got_int)
8879 	{
8880 	    fp = find_func(name);
8881 	    if (fp != NULL)
8882 	    {
8883 		list_func_head(fp, TRUE);
8884 		for (j = 0; j < fp->lines.ga_len && !got_int; ++j)
8885 		{
8886 		    msg_putchar('\n');
8887 		    msg_outnum((long)(j + 1));
8888 		    if (j < 9)
8889 			msg_putchar(' ');
8890 		    if (j < 99)
8891 			msg_putchar(' ');
8892 		    msg_prt_line(FUNCLINE(fp, j));
8893 		    out_flush();	/* show a line at a time */
8894 		    ui_breakcheck();
8895 		}
8896 		if (!got_int)
8897 		{
8898 		    msg_putchar('\n');
8899 		    msg_puts((char_u *)"   endfunction");
8900 		}
8901 	    }
8902 	    else
8903 		EMSG2(_("E123: Undefined function: %s"), eap->arg);
8904 	}
8905 	goto erret_name;
8906     }
8907 
8908     /*
8909      * ":function name(arg1, arg2)" Define function.
8910      */
8911     p = skipwhite(p);
8912     if (*p != '(')
8913     {
8914 	if (!eap->skip)
8915 	{
8916 	    EMSG2(_("E124: Missing '(': %s"), eap->arg);
8917 	    goto erret_name;
8918 	}
8919 	/* attempt to continue by skipping some text */
8920 	if (vim_strchr(p, '(') != NULL)
8921 	    p = vim_strchr(p, '(');
8922     }
8923     p = skipwhite(p + 1);
8924 
8925     ga_init2(&newargs, (int)sizeof(char_u *), 3);
8926     ga_init2(&newlines, (int)sizeof(char_u *), 3);
8927 
8928     /*
8929      * Isolate the arguments: "arg1, arg2, ...)"
8930      */
8931     while (*p != ')')
8932     {
8933 	if (p[0] == '.' && p[1] == '.' && p[2] == '.')
8934 	{
8935 	    varargs = TRUE;
8936 	    p += 3;
8937 	    mustend = TRUE;
8938 	}
8939 	else
8940 	{
8941 	    arg = p;
8942 	    while (ASCII_ISALNUM(*p) || *p == '_')
8943 		++p;
8944 	    if (arg == p || isdigit(*arg)
8945 		    || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
8946 		    || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0))
8947 	    {
8948 		if (!eap->skip)
8949 		    EMSG2(_("E125: Illegal argument: %s"), arg);
8950 		break;
8951 	    }
8952 	    if (ga_grow(&newargs, 1) == FAIL)
8953 		goto erret;
8954 	    c = *p;
8955 	    *p = NUL;
8956 	    arg = vim_strsave(arg);
8957 	    if (arg == NULL)
8958 		goto erret;
8959 	    ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
8960 	    *p = c;
8961 	    newargs.ga_len++;
8962 	    newargs.ga_room--;
8963 	    if (*p == ',')
8964 		++p;
8965 	    else
8966 		mustend = TRUE;
8967 	}
8968 	p = skipwhite(p);
8969 	if (mustend && *p != ')')
8970 	{
8971 	    if (!eap->skip)
8972 		EMSG2(_(e_invarg2), eap->arg);
8973 	    break;
8974 	}
8975     }
8976     ++p;	/* skip the ')' */
8977 
8978     /* find extra arguments "range" and "abort" */
8979     for (;;)
8980     {
8981 	p = skipwhite(p);
8982 	if (STRNCMP(p, "range", 5) == 0)
8983 	{
8984 	    flags |= FC_RANGE;
8985 	    p += 5;
8986 	}
8987 	else if (STRNCMP(p, "abort", 5) == 0)
8988 	{
8989 	    flags |= FC_ABORT;
8990 	    p += 5;
8991 	}
8992 	else
8993 	    break;
8994     }
8995 
8996     if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg)
8997 	EMSG(_(e_trailing));
8998 
8999     /*
9000      * Read the body of the function, until ":endfunction" is found.
9001      */
9002     if (KeyTyped)
9003     {
9004 	/* Check if the function already exists, don't let the user type the
9005 	 * whole function before telling him it doesn't work!  For a script we
9006 	 * need to skip the body to be able to find what follows. */
9007 	if (!eap->skip && !eap->forceit && find_func(name) != NULL)
9008 	    EMSG2(_(e_funcexts), name);
9009 
9010 	msg_putchar('\n');	    /* don't overwrite the function name */
9011 	cmdline_row = msg_row;
9012     }
9013 
9014     indent = 2;
9015     nesting = 0;
9016     for (;;)
9017     {
9018 	msg_scroll = TRUE;
9019 	need_wait_return = FALSE;
9020 	if (eap->getline == NULL)
9021 	    theline = getcmdline(':', 0L, indent);
9022 	else
9023 	    theline = eap->getline(':', eap->cookie, indent);
9024 	if (KeyTyped)
9025 	    lines_left = Rows - 1;
9026 	if (theline == NULL)
9027 	{
9028 	    EMSG(_("E126: Missing :endfunction"));
9029 	    goto erret;
9030 	}
9031 
9032 	if (skip_until != NULL)
9033 	{
9034 	    /* between ":append" and "." and between ":python <<EOF" and "EOF"
9035 	     * don't check for ":endfunc". */
9036 	    if (STRCMP(theline, skip_until) == 0)
9037 	    {
9038 		vim_free(skip_until);
9039 		skip_until = NULL;
9040 	    }
9041 	}
9042 	else
9043 	{
9044 	    /* skip ':' and blanks*/
9045 	    for (p = theline; vim_iswhite(*p) || *p == ':'; ++p)
9046 		;
9047 
9048 	    /* Check for "endfunction" (should be more strict...). */
9049 	    if (STRNCMP(p, "endf", 4) == 0 && nesting-- == 0)
9050 	    {
9051 		vim_free(theline);
9052 		break;
9053 	    }
9054 
9055 	    /* Increase indent inside "if", "while", and "try", decrease
9056 	     * at "end". */
9057 	    if (indent > 2 && STRNCMP(p, "end", 3) == 0)
9058 		indent -= 2;
9059 	    else if (STRNCMP(p, "if", 2) == 0 || STRNCMP(p, "wh", 2) == 0
9060 		    || STRNCMP(p, "try", 3) == 0)
9061 		indent += 2;
9062 
9063 	    /* Check for defining a function inside this function. */
9064 	    if (STRNCMP(p, "fu", 2) == 0)
9065 	    {
9066 		p = skipwhite(skiptowhite(p));
9067 		p += eval_fname_script(p);
9068 		if (ASCII_ISALPHA(*p))
9069 		{
9070 		    vim_free(trans_function_name(&p, TRUE, FALSE));
9071 		    if (*skipwhite(p) == '(')
9072 		    {
9073 			++nesting;
9074 			indent += 2;
9075 		    }
9076 		}
9077 	    }
9078 
9079 	    /* Check for ":append" or ":insert". */
9080 	    p = skip_range(p, NULL);
9081 	    if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
9082 		    || (p[0] == 'i'
9083 			&& (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
9084 				&& (!ASCII_ISALPHA(p[2]) || (p[2] == 's'))))))
9085 		skip_until = vim_strsave((char_u *)".");
9086 
9087 	    /* Check for ":python <<EOF", ":tcl <<EOF", etc. */
9088 	    arg = skipwhite(skiptowhite(p));
9089 	    if (arg[0] == '<' && arg[1] =='<'
9090 		    && ((p[0] == 'p' && p[1] == 'y'
9091 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 't'))
9092 			|| (p[0] == 'p' && p[1] == 'e'
9093 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
9094 			|| (p[0] == 't' && p[1] == 'c'
9095 				    && (!ASCII_ISALPHA(p[2]) || p[2] == 'l'))
9096 			|| (p[0] == 'r' && p[1] == 'u' && p[2] == 'b'
9097 				    && (!ASCII_ISALPHA(p[3]) || p[3] == 'y'))
9098 			))
9099 	    {
9100 		/* ":python <<" continues until a dot, like ":append" */
9101 		p = skipwhite(arg + 2);
9102 		if (*p == NUL)
9103 		    skip_until = vim_strsave((char_u *)".");
9104 		else
9105 		    skip_until = vim_strsave(p);
9106 	    }
9107 	}
9108 
9109 	/* Add the line to the function. */
9110 	if (ga_grow(&newlines, 1) == FAIL)
9111 	    goto erret;
9112 	((char_u **)(newlines.ga_data))[newlines.ga_len] = theline;
9113 	newlines.ga_len++;
9114 	newlines.ga_room--;
9115     }
9116 
9117     /* Don't define the function when skipping commands or when an error was
9118      * detected. */
9119     if (eap->skip || did_emsg)
9120 	goto erret;
9121 
9122     /*
9123      * If there are no errors, add the function
9124      */
9125     fp = find_func(name);
9126     if (fp != NULL)
9127     {
9128 	if (!eap->forceit)
9129 	{
9130 	    EMSG2(_(e_funcexts), name);
9131 	    goto erret;
9132 	}
9133 	if (fp->calls)
9134 	{
9135 	    EMSG2(_("E127: Cannot redefine function %s: It is in use"), name);
9136 	    goto erret;
9137 	}
9138 	/* redefine existing function */
9139 	ga_clear_strings(&(fp->args));
9140 	ga_clear_strings(&(fp->lines));
9141 	vim_free(name);
9142     }
9143     else
9144     {
9145 	fp = (ufunc_T *)alloc((unsigned)sizeof(ufunc_T));
9146 	if (fp == NULL)
9147 	    goto erret;
9148 	/* insert the new function in the function list */
9149 	fp->next = firstfunc;
9150 	firstfunc = fp;
9151 	fp->name = name;
9152     }
9153     fp->args = newargs;
9154     fp->lines = newlines;
9155     fp->varargs = varargs;
9156     fp->flags = flags;
9157     fp->calls = 0;
9158     fp->script_ID = current_SID;
9159 #ifdef FEAT_MAGIC_BRACES
9160     did_emsg |= saved_did_emsg;
9161 #endif
9162     vim_free(skip_until);
9163     return;
9164 
9165 erret:
9166     vim_free(skip_until);
9167     ga_clear_strings(&newargs);
9168     ga_clear_strings(&newlines);
9169 erret_name:
9170     vim_free(name);
9171 #ifdef FEAT_MAGIC_BRACES
9172     did_emsg |= saved_did_emsg;
9173 #endif
9174 }
9175 
9176 /*
9177  * Get a function name, translating "<SID>" and "<SNR>".
9178  * Returns the function name in allocated memory, or NULL for failure.
9179  * Advances "pp" to just after the function name (if no error).
9180  */
9181     static char_u *
9182 trans_function_name(pp, skip, internal)
9183     char_u	**pp;
9184     int		skip;		/* only find the end, don't evaluate */
9185     int		internal;	/* TRUE if internal function name OK */
9186 {
9187     char_u	*name;
9188     char_u	*start;
9189     char_u	*end;
9190     int		lead;
9191     char_u	sid_buf[20];
9192     char_u	*temp_string = NULL;
9193     char_u	*expr_start, *expr_end;
9194     int		len;
9195 
9196     /* A name starting with "<SID>" or "<SNR>" is local to a script. */
9197     start = *pp;
9198     lead = eval_fname_script(start);
9199     if (lead > 0)
9200 	start += lead;
9201     end = find_name_end(start, &expr_start, &expr_end);
9202     if (end == start)
9203     {
9204 	if (!skip)
9205 	    EMSG(_("E129: Function name required"));
9206 	return NULL;
9207     }
9208 #ifdef FEAT_MAGIC_BRACES
9209     if (expr_start != NULL && !skip)
9210     {
9211 	/* expand magic curlies */
9212 	temp_string = make_expanded_name(start, expr_start, expr_end, end);
9213 	if (temp_string == NULL)
9214 	{
9215 	    /*
9216 	     * Report an invalid expression in braces, unless the expression
9217 	     * evaluation has been cancelled due to an aborting error, an
9218 	     * interrupt, or an exception.
9219 	     */
9220 	    if (!aborting())
9221 		EMSG2(_(e_invarg2), start);
9222 	    else
9223 		*pp = end;
9224 	    return NULL;
9225 	}
9226 	start = temp_string;
9227 	len = (int)STRLEN(temp_string);
9228     }
9229     else
9230 #endif
9231 	len = (int)(end - start);
9232 
9233     /*
9234      * Copy the function name to allocated memory.
9235      * Accept <SID>name() inside a script, translate into <SNR>123_name().
9236      * Accept <SNR>123_name() outside a script.
9237      */
9238     if (skip)
9239 	lead = 0;	/* do nothing */
9240     else if (lead > 0)
9241     {
9242 	lead = 3;
9243 	if (eval_fname_sid(*pp))	/* If it's "<SID>" */
9244 	{
9245 	    if (current_SID <= 0)
9246 	    {
9247 		EMSG(_(e_usingsid));
9248 		return NULL;
9249 	    }
9250 	    sprintf((char *)sid_buf, "%ld_", (long)current_SID);
9251 	    lead += (int)STRLEN(sid_buf);
9252 	}
9253     }
9254     else if (!internal && !ASCII_ISUPPER(*start))
9255     {
9256 	EMSG2(_("E128: Function name must start with a capital: %s"), start);
9257 	return NULL;
9258     }
9259     name = alloc((unsigned)(len + lead + 1));
9260     if (name != NULL)
9261     {
9262 	if (lead > 0)
9263 	{
9264 	    name[0] = K_SPECIAL;
9265 	    name[1] = KS_EXTRA;
9266 	    name[2] = (int)KE_SNR;
9267 	    if (eval_fname_sid(*pp))	/* If it's "<SID>" */
9268 		STRCPY(name + 3, sid_buf);
9269 	}
9270 	mch_memmove(name + lead, start, (size_t)len);
9271 	name[len + lead] = NUL;
9272     }
9273     *pp = end;
9274 
9275     vim_free(temp_string);
9276     return name;
9277 }
9278 
9279 /*
9280  * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case).
9281  * Return 2 if "p" starts with "s:".
9282  * Return 0 otherwise.
9283  */
9284     static int
9285 eval_fname_script(p)
9286     char_u	*p;
9287 {
9288     if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0
9289 					  || STRNICMP(p + 1, "SNR>", 4) == 0))
9290 	return 5;
9291     if (p[0] == 's' && p[1] == ':')
9292 	return 2;
9293     return 0;
9294 }
9295 
9296 /*
9297  * Return TRUE if "p" starts with "<SID>" or "s:".
9298  * Only works if eval_fname_script() returned non-zero for "p"!
9299  */
9300     static int
9301 eval_fname_sid(p)
9302     char_u	*p;
9303 {
9304     return (*p == 's' || TOUPPER_ASC(p[2]) == 'I');
9305 }
9306 
9307 /*
9308  * List the head of the function: "name(arg1, arg2)".
9309  */
9310     static void
9311 list_func_head(fp, indent)
9312     ufunc_T	*fp;
9313     int		indent;
9314 {
9315     int		j;
9316 
9317     msg_start();
9318     if (indent)
9319 	MSG_PUTS("   ");
9320     MSG_PUTS("function ");
9321     if (fp->name[0] == K_SPECIAL)
9322     {
9323 	MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
9324 	msg_puts(fp->name + 3);
9325     }
9326     else
9327 	msg_puts(fp->name);
9328     msg_putchar('(');
9329     for (j = 0; j < fp->args.ga_len; ++j)
9330     {
9331 	if (j)
9332 	    MSG_PUTS(", ");
9333 	msg_puts(FUNCARG(fp, j));
9334     }
9335     if (fp->varargs)
9336     {
9337 	if (j)
9338 	    MSG_PUTS(", ");
9339 	MSG_PUTS("...");
9340     }
9341     msg_putchar(')');
9342 }
9343 
9344 /*
9345  * Find a function by name, return pointer to it in ufuncs.
9346  * Return NULL for unknown function.
9347  */
9348     static ufunc_T *
9349 find_func(name)
9350     char_u	*name;
9351 {
9352     ufunc_T	*fp;
9353 
9354     for (fp = firstfunc; fp != NULL; fp = fp->next)
9355 	if (STRCMP(name, fp->name) == 0)
9356 	    break;
9357     return fp;
9358 }
9359 
9360 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
9361 
9362 /*
9363  * Function given to ExpandGeneric() to obtain the list of user defined
9364  * function names.
9365  */
9366     char_u *
9367 get_user_func_name(xp, idx)
9368     expand_T	*xp;
9369     int		idx;
9370 {
9371     static ufunc_T *fp = NULL;
9372 
9373     if (idx == 0)
9374 	fp = firstfunc;
9375     if (fp != NULL)
9376     {
9377 	if (STRLEN(fp->name) + 4 >= IOSIZE)
9378 	    return fp->name;	/* prevents overflow */
9379 
9380 	cat_func_name(IObuff, fp);
9381 	if (xp->xp_context != EXPAND_USER_FUNC)
9382 	{
9383 	    STRCAT(IObuff, "(");
9384 	    if (!fp->varargs && fp->args.ga_len == 0)
9385 		STRCAT(IObuff, ")");
9386 	}
9387 
9388 	fp = fp->next;
9389 	return IObuff;
9390     }
9391     return NULL;
9392 }
9393 
9394 #endif /* FEAT_CMDL_COMPL */
9395 
9396 /*
9397  * Copy the function name of "fp" to buffer "buf".
9398  * "buf" must be able to hold the function name plus three bytes.
9399  * Takes care of script-local function names.
9400  */
9401     static void
9402 cat_func_name(buf, fp)
9403     char_u	*buf;
9404     ufunc_T	*fp;
9405 {
9406     if (fp->name[0] == K_SPECIAL)
9407     {
9408 	STRCPY(buf, "<SNR>");
9409 	STRCAT(buf, fp->name + 3);
9410     }
9411     else
9412 	STRCPY(buf, fp->name);
9413 }
9414 
9415 /*
9416  * ":delfunction {name}"
9417  */
9418     void
9419 ex_delfunction(eap)
9420     exarg_T	*eap;
9421 {
9422     ufunc_T	*fp = NULL, *pfp;
9423     char_u	*p;
9424     char_u	*name;
9425 
9426     p = eap->arg;
9427     name = trans_function_name(&p, eap->skip, FALSE);
9428     if (name == NULL)
9429 	return;
9430     if (!ends_excmd(*skipwhite(p)))
9431     {
9432 	vim_free(name);
9433 	EMSG(_(e_trailing));
9434 	return;
9435     }
9436     eap->nextcmd = check_nextcmd(p);
9437     if (eap->nextcmd != NULL)
9438 	*p = NUL;
9439 
9440     if (!eap->skip)
9441 	fp = find_func(name);
9442     vim_free(name);
9443 
9444     if (!eap->skip)
9445     {
9446 	if (fp == NULL)
9447 	{
9448 	    EMSG2(_("E130: Undefined function: %s"), eap->arg);
9449 	    return;
9450 	}
9451 	if (fp->calls)
9452 	{
9453 	    EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg);
9454 	    return;
9455 	}
9456 
9457 	/* clear this function */
9458 	vim_free(fp->name);
9459 	ga_clear_strings(&(fp->args));
9460 	ga_clear_strings(&(fp->lines));
9461 
9462 	/* remove the function from the function list */
9463 	if (firstfunc == fp)
9464 	    firstfunc = fp->next;
9465 	else
9466 	{
9467 	    for (pfp = firstfunc; pfp != NULL; pfp = pfp->next)
9468 		if (pfp->next == fp)
9469 		{
9470 		    pfp->next = fp->next;
9471 		    break;
9472 		}
9473 	}
9474 	vim_free(fp);
9475     }
9476 }
9477 
9478 /*
9479  * Call a user function.
9480  */
9481     static void
9482 call_user_func(fp, argcount, argvars, retvar, firstline, lastline)
9483     ufunc_T	*fp;		/* pointer to function */
9484     int		argcount;	/* nr of args */
9485     VAR		argvars;	/* arguments */
9486     VAR		retvar;		/* return value */
9487     linenr_T	firstline;	/* first line of range */
9488     linenr_T	lastline;	/* last line of range */
9489 {
9490     char_u		*save_sourcing_name;
9491     linenr_T		save_sourcing_lnum;
9492     scid_T		save_current_SID;
9493     struct funccall	fc;
9494     struct funccall	*save_fcp = current_funccal;
9495     int			save_did_emsg;
9496     static int		depth = 0;
9497 
9498     /* If depth of calling is getting too high, don't execute the function */
9499     if (depth >= p_mfd)
9500     {
9501 	EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'"));
9502 	retvar->var_type = VAR_NUMBER;
9503 	retvar->var_val.var_number = -1;
9504 	return;
9505     }
9506     ++depth;
9507 
9508     line_breakcheck();		/* check for CTRL-C hit */
9509 
9510     /* set local variables */
9511     var_init(&fc.l_vars);
9512     fc.func = fp;
9513     fc.argcount = argcount;
9514     fc.argvars = argvars;
9515     fc.retvar = retvar;
9516     retvar->var_val.var_number = 0;
9517     fc.linenr = 0;
9518     fc.returned = FALSE;
9519     fc.level = ex_nesting_level;
9520     fc.a0_var.var_type = VAR_NUMBER;
9521     fc.a0_var.var_val.var_number = argcount - fp->args.ga_len;
9522     fc.a0_var.var_name = NULL;
9523     current_funccal = &fc;
9524     fc.firstline.var_type = VAR_NUMBER;
9525     fc.firstline.var_val.var_number = firstline;
9526     fc.firstline.var_name = NULL;
9527     fc.lastline.var_type = VAR_NUMBER;
9528     fc.lastline.var_val.var_number = lastline;
9529     fc.lastline.var_name = NULL;
9530     /* Check if this function has a breakpoint. */
9531     fc.breakpoint = dbg_find_breakpoint(FALSE, fp->name, (linenr_T)0);
9532     fc.dbg_tick = debug_tick;
9533 
9534     /* Don't redraw while executing the function. */
9535     ++RedrawingDisabled;
9536     save_sourcing_name = sourcing_name;
9537     save_sourcing_lnum = sourcing_lnum;
9538     sourcing_lnum = 1;
9539     sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0
9540 		: STRLEN(save_sourcing_name)) + STRLEN(fp->name) + 13));
9541     if (sourcing_name != NULL)
9542     {
9543 	if (save_sourcing_name != NULL
9544 			  && STRNCMP(save_sourcing_name, "function ", 9) == 0)
9545 	    sprintf((char *)sourcing_name, "%s..", save_sourcing_name);
9546 	else
9547 	    STRCPY(sourcing_name, "function ");
9548 	cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
9549 
9550 	if (p_verbose >= 12)
9551 	{
9552 	    ++no_wait_return;
9553 	    msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
9554 	    msg_str((char_u *)_("calling %s"), sourcing_name);
9555 	    if (p_verbose >= 14)
9556 	    {
9557 		int	i;
9558 		char_u	buf[MSG_BUF_LEN];
9559 
9560 		msg_puts((char_u *)"(");
9561 		for (i = 0; i < argcount; ++i)
9562 		{
9563 		    if (i > 0)
9564 			msg_puts((char_u *)", ");
9565 		    if (argvars[i].var_type == VAR_NUMBER)
9566 			msg_outnum((long)argvars[i].var_val.var_number);
9567 		    else
9568 		    {
9569 			trunc_string(get_var_string(&argvars[i]),
9570 							    buf, MSG_BUF_LEN);
9571 			msg_puts((char_u *)"\"");
9572 			msg_puts(buf);
9573 			msg_puts((char_u *)"\"");
9574 		    }
9575 		}
9576 		msg_puts((char_u *)")");
9577 	    }
9578 	    msg_puts((char_u *)"\n");   /* don't overwrite this either */
9579 	    cmdline_row = msg_row;
9580 	    --no_wait_return;
9581 	}
9582     }
9583     save_current_SID = current_SID;
9584     current_SID = fp->script_ID;
9585     save_did_emsg = did_emsg;
9586     did_emsg = FALSE;
9587 
9588     /* call do_cmdline() to execute the lines */
9589     do_cmdline(NULL, get_func_line, (void *)&fc,
9590 				     DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
9591 
9592     --RedrawingDisabled;
9593 
9594     /* when the function was aborted because of an error, return -1 */
9595     if ((did_emsg && (fp->flags & FC_ABORT)) || retvar->var_type == VAR_UNKNOWN)
9596     {
9597 	clear_var(retvar);
9598 	retvar->var_type = VAR_NUMBER;
9599 	retvar->var_val.var_number = -1;
9600     }
9601 
9602     /* when being verbose, mention the return value */
9603     if (p_verbose >= 12)
9604     {
9605 	char_u	*sn, *val;
9606 
9607 	++no_wait_return;
9608 	msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
9609 
9610 	/* Make sure the output fits in IObuff. */
9611 	sn = sourcing_name;
9612 	if (STRLEN(sourcing_name) > IOSIZE / 2 - 50)
9613 	    sn = sourcing_name + STRLEN(sourcing_name) - (IOSIZE / 2 - 50);
9614 
9615 	if (aborting())
9616 	    smsg((char_u *)_("%s aborted"), sn);
9617 	else if (fc.retvar->var_type == VAR_NUMBER)
9618 	    smsg((char_u *)_("%s returning #%ld"), sn,
9619 				       (long)fc.retvar->var_val.var_number);
9620 	else if (fc.retvar->var_type == VAR_STRING)
9621 	{
9622 	    val = get_var_string(fc.retvar);
9623 	    if (STRLEN(val) > IOSIZE / 2 - 50)
9624 		val = val + STRLEN(val) - (IOSIZE / 2 - 50);
9625 	    smsg((char_u *)_("%s returning \"%s\""), sn, val);
9626 	}
9627 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
9628 	cmdline_row = msg_row;
9629 	--no_wait_return;
9630     }
9631 
9632     vim_free(sourcing_name);
9633     sourcing_name = save_sourcing_name;
9634     sourcing_lnum = save_sourcing_lnum;
9635     current_SID = save_current_SID;
9636 
9637     if (p_verbose >= 12 && sourcing_name != NULL)
9638     {
9639 	++no_wait_return;
9640 	msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
9641 	msg_str((char_u *)_("continuing in %s"), sourcing_name);
9642 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
9643 	cmdline_row = msg_row;
9644 	--no_wait_return;
9645     }
9646 
9647     did_emsg |= save_did_emsg;
9648     current_funccal = save_fcp;
9649 
9650     var_clear(&fc.l_vars);		/* free all local variables */
9651     --depth;
9652 }
9653 
9654 /*
9655  * ":return [expr]"
9656  */
9657     void
9658 ex_return(eap)
9659     exarg_T	*eap;
9660 {
9661     char_u	*arg = eap->arg;
9662     var		retvar;
9663     int		returning = FALSE;
9664 
9665     if (current_funccal == NULL)
9666     {
9667 	EMSG(_("E133: :return not inside a function"));
9668 	return;
9669     }
9670 
9671     if (eap->skip)
9672 	++emsg_skip;
9673 
9674     eap->nextcmd = NULL;
9675     if ((*arg != NUL && *arg != '|' && *arg != '\n')
9676 	    && eval0(arg, &retvar, &eap->nextcmd, !eap->skip) != FAIL)
9677     {
9678 	if (!eap->skip)
9679 	    returning = do_return(eap, FALSE, TRUE, &retvar);
9680 	else
9681 	    clear_var(&retvar);
9682     }
9683     /* It's safer to return also on error. */
9684     else if (!eap->skip)
9685     {
9686 	/*
9687 	 * Return unless the expression evaluation has been cancelled due to an
9688 	 * aborting error, an interrupt, or an exception.
9689 	 */
9690 	if (!aborting())
9691 	    returning = do_return(eap, FALSE, TRUE, NULL);
9692     }
9693 
9694     /* When skipping or the return gets pending, advance to the next command
9695      * in this line (!returning).  Otherwise, ignore the rest of the line.
9696      * Following lines will be ignored by get_func_line(). */
9697     if (returning)
9698 	eap->nextcmd = NULL;
9699     else if (eap->nextcmd == NULL)	    /* no argument */
9700 	eap->nextcmd = check_nextcmd(arg);
9701 
9702     if (eap->skip)
9703 	--emsg_skip;
9704 }
9705 
9706 /*
9707  * Return from a function.  Possibly makes the return pending.  Also called
9708  * for a pending return at the ":endtry" or after returning from an extra
9709  * do_cmdline().  "reanimate" is used in the latter case.  "is_cmd" is set
9710  * when called due to a ":return" command.  "value" may point to a variable
9711  * with the return value.  Returns TRUE when the return can be carried out,
9712  * FALSE when the return gets pending.
9713  */
9714     int
9715 do_return(eap, reanimate, is_cmd, value)
9716     exarg_T	*eap;
9717     int		reanimate;
9718     int		is_cmd;
9719     void	*value;
9720 {
9721     int		idx;
9722     struct condstack *cstack = eap->cstack;
9723 
9724     if (reanimate)
9725 	/* Undo the return. */
9726 	current_funccal->returned = FALSE;
9727 
9728     /*
9729      * Cleanup (and inactivate) conditionals, but stop when a try conditional
9730      * not in its finally clause (which then is to be executed next) is found.
9731      * In this case, make the ":return" pending for execution at the ":endtry".
9732      * Otherwise, return normally.
9733      */
9734     idx = cleanup_conditionals(eap->cstack, 0, TRUE);
9735     if (idx >= 0)
9736     {
9737 	cstack->cs_pending[idx] = CSTP_RETURN;
9738 
9739 	if (!is_cmd && !reanimate)
9740 	    /* A pending return again gets pending.  "value" points to an
9741 	     * allocated variable with the value of the original ":return"'s
9742 	     * argument if present or is NULL else. */
9743 	    cstack->cs_retvar[idx] = value;
9744 	else
9745 	{
9746 	    /* When undoing a return in order to make it pending, get the stored
9747 	     * return value. */
9748 	    if (reanimate)
9749 		value = current_funccal->retvar;
9750 
9751 	    if (value != NULL)
9752 	    {
9753 		/* Store the value of the pending return. */
9754 		if ((cstack->cs_retvar[idx] = alloc_var()) != NULL)
9755 		    *(VAR)cstack->cs_retvar[idx] = *(VAR)value;
9756 		else
9757 		    EMSG(_(e_outofmem));
9758 	    }
9759 	    else
9760 		cstack->cs_retvar[idx] = NULL;
9761 
9762 	    if (reanimate)
9763 	    {
9764 		/* The pending return value could be overwritten by a ":return"
9765 		 * without argument in a finally clause; reset the default
9766 		 * return value. */
9767 		current_funccal->retvar->var_type = VAR_NUMBER;
9768 		current_funccal->retvar->var_val.var_number = 0;
9769 	    }
9770 	}
9771 	report_make_pending(CSTP_RETURN, value);
9772     }
9773     else
9774     {
9775 	current_funccal->returned = TRUE;
9776 
9777 	/* If the return is carried out now, store the return value.  For
9778 	 * a return immediately after reanimation, the value is already
9779 	 * there. */
9780 	if (!reanimate && value != NULL)
9781 	{
9782 	    clear_var(current_funccal->retvar);
9783 	    *current_funccal->retvar = *(VAR)value;
9784 	    if (!is_cmd)
9785 		vim_free(value);
9786 	}
9787     }
9788 
9789     return idx < 0;
9790 }
9791 
9792 /*
9793  * Free the variable with a pending return value.
9794  */
9795     void
9796 discard_pending_return(retvar)
9797     void	*retvar;
9798 {
9799     /* The variable was copied from one with an undefined var_name.  So we can't
9800      * use free_var() to clear and free it. */
9801     clear_var((VAR)retvar);
9802     vim_free(retvar);
9803 }
9804 
9805 /*
9806  * Generate a return command for producing the value of "retvar".  The result
9807  * is an allocated string.  Used by report_pending() for verbose messages.
9808  */
9809     char_u *
9810 get_return_cmd(retvar)
9811     void	*retvar;
9812 {
9813     char_u	*s = IObuff;
9814 
9815     if (retvar == NULL || ((VAR)retvar)->var_type == VAR_UNKNOWN)
9816 	s = (char_u *)":return";
9817     else if (((VAR)retvar)->var_type == VAR_STRING)
9818 	sprintf((char *)IObuff, ":return \"%s\"",
9819 		((VAR)retvar)->var_val.var_string);
9820     else
9821 	sprintf((char *)IObuff, ":return %ld",
9822 		(long)(((VAR)retvar)->var_val.var_number));
9823     return vim_strsave(s);
9824 }
9825 
9826 /*
9827  * Get next function line.
9828  * Called by do_cmdline() to get the next line.
9829  * Returns allocated string, or NULL for end of function.
9830  */
9831 /* ARGSUSED */
9832     char_u *
9833 get_func_line(c, cookie, indent)
9834     int	    c;		    /* not used */
9835     void    *cookie;
9836     int	    indent;	    /* not used */
9837 {
9838     struct funccall	*fcp = (struct funccall *)cookie;
9839     char_u		*retval;
9840     garray_T		*gap;  /* growarray with function lines */
9841 
9842     /* If breakpoints have been added/deleted need to check for it. */
9843     if (fcp->dbg_tick != debug_tick)
9844     {
9845 	fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name,
9846 							       sourcing_lnum);
9847 	fcp->dbg_tick = debug_tick;
9848     }
9849 
9850     gap = &fcp->func->lines;
9851     if ((fcp->func->flags & FC_ABORT) && did_emsg && !aborted_in_try())
9852 	retval = NULL;
9853     else if (fcp->returned || fcp->linenr >= gap->ga_len)
9854 	retval = NULL;
9855     else
9856     {
9857 	retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
9858 	sourcing_lnum = fcp->linenr;
9859     }
9860 
9861     /* Did we encounter a breakpoint? */
9862     if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum)
9863     {
9864 	dbg_breakpoint(fcp->func->name, sourcing_lnum);
9865 	/* Find next breakpoint. */
9866 	fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name,
9867 							       sourcing_lnum);
9868 	fcp->dbg_tick = debug_tick;
9869     }
9870 
9871     return retval;
9872 }
9873 
9874 /*
9875  * Return TRUE if the currently active function should be ended, because a
9876  * return was encountered or an error occured.  Used inside a ":while".
9877  */
9878     int
9879 func_has_ended(cookie)
9880     void    *cookie;
9881 {
9882     struct funccall  *fcp = (struct funccall *)cookie;
9883 
9884     /* Ignore the "abort" flag if the abortion behavior has been changed due to
9885      * an error inside a try conditional. */
9886     return (((fcp->func->flags & FC_ABORT) && did_emsg && !aborted_in_try())
9887 	    || fcp->returned);
9888 }
9889 
9890 /*
9891  * return TRUE if cookie indicates a function which "abort"s on errors.
9892  */
9893     int
9894 func_has_abort(cookie)
9895     void    *cookie;
9896 {
9897     return ((struct funccall *)cookie)->func->flags & FC_ABORT;
9898 }
9899 
9900 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)
9901 typedef enum
9902 {
9903     VAR_FLAVOUR_DEFAULT,
9904     VAR_FLAVOUR_SESSION,
9905     VAR_FLAVOUR_VIMINFO
9906 } var_flavour_T;
9907 
9908 static var_flavour_T var_flavour __ARGS((char_u *varname));
9909 
9910     static var_flavour_T
9911 var_flavour(varname)
9912     char_u *varname;
9913 {
9914     char_u *p = varname;
9915 
9916     if (ASCII_ISUPPER(*p))
9917     {
9918 	while (*(++p))
9919 	    if (ASCII_ISLOWER(*p))
9920 		return VAR_FLAVOUR_SESSION;
9921 	return VAR_FLAVOUR_VIMINFO;
9922     }
9923     else
9924 	return VAR_FLAVOUR_DEFAULT;
9925 }
9926 #endif
9927 
9928 #if defined(FEAT_VIMINFO) || defined(PROTO)
9929 /*
9930  * Restore global vars that start with a capital from the viminfo file
9931  */
9932     int
9933 read_viminfo_varlist(virp, writing)
9934     vir_T	*virp;
9935     int		writing;
9936 {
9937     char_u	*tab;
9938     int		is_string = FALSE;
9939     VAR		varp = NULL;
9940     char_u	*val;
9941 
9942     if (!writing && (find_viminfo_parameter('!') != NULL))
9943     {
9944 	tab = vim_strchr(virp->vir_line + 1, '\t');
9945 	if (tab != NULL)
9946 	{
9947 	    *tab++ = '\0';	/* isolate the variable name */
9948 	    if (*tab == 'S')	/* string var */
9949 		is_string = TRUE;
9950 
9951 	    tab = vim_strchr(tab, '\t');
9952 	    if (tab != NULL)
9953 	    {
9954 		/* create a nameless variable to hold the value */
9955 		if (is_string)
9956 		{
9957 		    val = viminfo_readstring(virp,
9958 				       (int)(tab - virp->vir_line + 1), TRUE);
9959 		    if (val != NULL)
9960 			varp = alloc_string_var(val);
9961 		}
9962 		else
9963 		{
9964 		    varp = alloc_var();
9965 		    if (varp != NULL)
9966 		    {
9967 			varp->var_type = VAR_NUMBER;
9968 			varp->var_val.var_number = atol((char *)tab + 1);
9969 		    }
9970 		}
9971 		/* assign the value to the variable */
9972 		if (varp != NULL)
9973 		{
9974 		    set_var(virp->vir_line + 1, varp);
9975 		    free_var(varp);
9976 		}
9977 	    }
9978 	}
9979     }
9980 
9981     return viminfo_readline(virp);
9982 }
9983 
9984 /*
9985  * Write global vars that start with a capital to the viminfo file
9986  */
9987     void
9988 write_viminfo_varlist(fp)
9989     FILE    *fp;
9990 {
9991     garray_T	*gap = &variables;		/* global variable */
9992     VAR		this_var;
9993     int		i;
9994 
9995     if (find_viminfo_parameter('!') == NULL)
9996 	return;
9997 
9998     fprintf(fp, _("\n# global variables:\n"));
9999     for (i = gap->ga_len; --i >= 0; )
10000     {
10001 	this_var = &VAR_GAP_ENTRY(i, gap);
10002 	if (this_var->var_name != NULL
10003 		&& var_flavour(this_var->var_name) == VAR_FLAVOUR_VIMINFO)
10004 	{
10005 	    fprintf(fp, "!%s\t%s\t", this_var->var_name,
10006 			  (this_var->var_type == VAR_STRING) ? "STR" : "NUM");
10007 	    viminfo_writestring(fp, get_var_string(this_var));
10008 	}
10009     }
10010 }
10011 #endif
10012 
10013 #if defined(FEAT_SESSION) || defined(PROTO)
10014     int
10015 store_session_globals(fd)
10016     FILE	*fd;
10017 {
10018     garray_T	*gap = &variables;		/* global variable */
10019     VAR		this_var;
10020     int		i;
10021     char_u	*p, *t;
10022 
10023     for (i = gap->ga_len; --i >= 0; )
10024     {
10025 	this_var = &VAR_GAP_ENTRY(i, gap);
10026 	if (this_var->var_name != NULL)
10027 	{
10028 	    if (var_flavour(this_var->var_name) == VAR_FLAVOUR_SESSION)
10029 	    {
10030 		/* Escapse special characters with a backslash.  Turn a LF and
10031 		 * CR into \n and \r. */
10032 		p = vim_strsave_escaped(get_var_string(this_var),
10033 							(char_u *)"\\\"\n\r");
10034 		if (p == NULL)	    /* out of memory */
10035 		    continue;
10036 		for (t = p; *t != NUL; ++t)
10037 		    if (*t == '\n')
10038 			*t = 'n';
10039 		    else if (*t == '\r')
10040 			*t = 'r';
10041 		if ((fprintf(fd, "let %s = %c%s%c",
10042 			    this_var->var_name,
10043 			    (this_var->var_type == VAR_STRING) ? '"' : ' ',
10044 			    p,
10045 			    (this_var->var_type == VAR_STRING) ? '"' : ' ') < 0)
10046 			|| put_eol(fd) == FAIL)
10047 		{
10048 		    vim_free(p);
10049 		    return FAIL;
10050 		}
10051 		vim_free(p);
10052 	    }
10053 
10054 	}
10055     }
10056     return OK;
10057 }
10058 #endif
10059 
10060 #endif /* FEAT_EVAL */
10061 
10062 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO)
10063 
10064 
10065 #ifdef WIN3264
10066 /*
10067  * Functions for ":8" filename modifier: get 8.3 version of a filename.
10068  */
10069 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen));
10070 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen));
10071 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen));
10072 
10073 /*
10074  * Get the short pathname of a file.
10075  * Returns 1 on success. *fnamelen is 0 for nonexistant path.
10076  */
10077     static int
10078 get_short_pathname(fnamep, bufp, fnamelen)
10079     char_u	**fnamep;
10080     char_u	**bufp;
10081     int		*fnamelen;
10082 {
10083     int		l,len;
10084     char_u	*newbuf;
10085 
10086     len = *fnamelen;
10087 
10088     l = GetShortPathName(*fnamep, *fnamep, len);
10089     if (l > len - 1)
10090     {
10091 	/* If that doesn't work (not enough space), then save the string
10092 	 * and try again with a new buffer big enough
10093 	 */
10094 	newbuf = vim_strnsave(*fnamep, l);
10095 	if (newbuf == NULL)
10096 	    return 0;
10097 
10098 	vim_free(*bufp);
10099 	*fnamep = *bufp = newbuf;
10100 
10101 	l = GetShortPathName(*fnamep,*fnamep,l+1);
10102 
10103 	/* Really should always succeed, as the buffer is big enough */
10104     }
10105 
10106     *fnamelen = l;
10107     return 1;
10108 }
10109 
10110 /*
10111  * Create a short path name.  Returns the length of the buffer it needs.
10112  * Doesn't copy over the end of the buffer passed in.
10113  */
10114     static int
10115 shortpath_for_invalid_fname(fname, bufp, fnamelen)
10116     char_u	**fname;
10117     char_u	**bufp;
10118     int		*fnamelen;
10119 {
10120     char_u	*s, *p, *pbuf2, *pbuf3;
10121     char_u	ch;
10122     int		l,len,len2,plen,slen;
10123 
10124     /* Make a copy */
10125     len2 = *fnamelen;
10126     pbuf2 = vim_strnsave(*fname, len2);
10127     pbuf3 = NULL;
10128 
10129     s = pbuf2 + len2 - 1; /* Find the end */
10130     slen = 1;
10131     plen = len2;
10132 
10133     l = 0;
10134     if (vim_ispathsep(*s))
10135     {
10136 	--s;
10137 	++slen;
10138 	--plen;
10139     }
10140 
10141     do
10142     {
10143 	/* Go back one path-seperator */
10144 	while (s > pbuf2 && !vim_ispathsep(*s))
10145 	{
10146 	    --s;
10147 	    ++slen;
10148 	    --plen;
10149 	}
10150 	if (s <= pbuf2)
10151 	    break;
10152 
10153 	/* Remeber the character that is about to be blatted */
10154 	ch = *s;
10155 	*s = 0; /* get_short_pathname requires a null-terminated string */
10156 
10157 	/* Try it in situ */
10158 	p = pbuf2;
10159 	if (!get_short_pathname(&p, &pbuf3, &plen))
10160 	{
10161 	    vim_free(pbuf2);
10162 	    return -1;
10163 	}
10164 	*s = ch;    /* Preserve the string */
10165     } while (plen == 0);
10166 
10167     if (plen > 0)
10168     {
10169 	/* Remeber the length of the new string.  */
10170 	*fnamelen = len = plen + slen;
10171 	vim_free(*bufp);
10172 	if (len > len2)
10173 	{
10174 	    /* If there's not enough space in the currently allocated string,
10175 	     * then copy it to a buffer big enough.
10176 	     */
10177 	    *fname= *bufp = vim_strnsave(p, len);
10178 	    if (*fname == NULL)
10179 		return -1;
10180 	}
10181 	else
10182 	{
10183 	    /* Transfer pbuf2 to being the main buffer  (it's big enough) */
10184 	    *fname = *bufp = pbuf2;
10185 	    if (p != pbuf2)
10186 		strncpy(*fname, p, plen);
10187 	    pbuf2 = NULL;
10188 	}
10189 	/* Concat the next bit */
10190 	strncpy(*fname + plen, s, slen);
10191 	(*fname)[len] = '\0';
10192     }
10193     vim_free(pbuf3);
10194     vim_free(pbuf2);
10195     return 0;
10196 }
10197 
10198 /*
10199  * Get a pathname for a partial path.
10200  */
10201     static int
10202 shortpath_for_partial(fnamep, bufp, fnamelen)
10203     char_u	**fnamep;
10204     char_u	**bufp;
10205     int		*fnamelen;
10206 {
10207     int		sepcount, len, tflen;
10208     char_u	*p;
10209     char_u	*pbuf, *tfname;
10210     int		hasTilde;
10211 
10212     /* Count up the path seperators from the RHS.. so we know which part
10213      * of the path to return.
10214      */
10215     sepcount = 0;
10216     for (p = *fnamep + *fnamelen - 1; p >= *fnamep; --p)
10217 	if (vim_ispathsep(*p))
10218 	    ++sepcount;
10219 
10220     /* Need full path first (use expand_env() to remove a "~/") */
10221     hasTilde = (**fnamep == '~');
10222     if (hasTilde)
10223 	pbuf = tfname = expand_env_save(*fnamep);
10224     else
10225 	pbuf = tfname = FullName_save(*fnamep, FALSE);
10226 
10227     len = tflen = STRLEN(tfname);
10228 
10229     if (!get_short_pathname(&tfname, &pbuf, &len))
10230 	return -1;
10231 
10232     if (len == 0)
10233     {
10234 	/* Don't have a valid filename, so shorten the rest of the
10235 	 * path if we can. This CAN give us invalid 8.3 filenames, but
10236 	 * there's not a lot of point in guessing what it might be.
10237 	 */
10238 	len = tflen;
10239 	if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1)
10240 	    return -1;
10241     }
10242 
10243     /* Count the paths backward to find the beginning of the desired string. */
10244     for (p = tfname + len - 1; p >= tfname; --p)
10245 	if (vim_ispathsep(*p))
10246 	{
10247 	    if (sepcount == 0 || (hasTilde && sepcount == 1))
10248 		break;
10249 	    else
10250 		sepcount --;
10251 	}
10252     if (hasTilde)
10253     {
10254 	--p;
10255 	if (p >= tfname)
10256 	    *p = '~';
10257 	else
10258 	    return -1;
10259     }
10260     else
10261 	++p;
10262 
10263     /* Copy in the string - p indexes into tfname - allocated at pbuf */
10264     vim_free(*bufp);
10265     *fnamelen = (int)STRLEN(p);
10266     *bufp = pbuf;
10267     *fnamep = p;
10268 
10269     return 0;
10270 }
10271 #endif /* WIN3264 */
10272 
10273 /*
10274  * Adjust a filename, according to a string of modifiers.
10275  * *fnamep must be NUL terminated when called.  When returning, the length is
10276  * determined by *fnamelen.
10277  * Returns valid flags.
10278  * When there is an error, *fnamep is set to NULL.
10279  */
10280     int
10281 modify_fname(src, usedlen, fnamep, bufp, fnamelen)
10282     char_u	*src;		/* string with modifiers */
10283     int		*usedlen;	/* characters after src that are used */
10284     char_u	**fnamep;	/* file name so far */
10285     char_u	**bufp;		/* buffer for allocated file name or NULL */
10286     int		*fnamelen;	/* length of fnamep */
10287 {
10288     int		valid = 0;
10289     char_u	*tail;
10290     char_u	*s, *p, *pbuf;
10291     char_u	dirname[MAXPATHL];
10292     int		c;
10293     int		has_fullname = 0;
10294 #ifdef WIN3264
10295     int		has_shortname = 0;
10296 #endif
10297 
10298 repeat:
10299     /* ":p" - full path/file_name */
10300     if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p')
10301     {
10302 	has_fullname = 1;
10303 
10304 	valid |= VALID_PATH;
10305 	*usedlen += 2;
10306 
10307 	/* Expand "~/path" for all systems and "~user/path" for Unix and VMS */
10308 	if ((*fnamep)[0] == '~'
10309 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME))
10310 		&& ((*fnamep)[1] == '/'
10311 # ifdef BACKSLASH_IN_FILENAME
10312 		    || (*fnamep)[1] == '\\'
10313 # endif
10314 		    || (*fnamep)[1] == NUL)
10315 
10316 #endif
10317 	   )
10318 	{
10319 	    *fnamep = expand_env_save(*fnamep);
10320 	    vim_free(*bufp);	/* free any allocated file name */
10321 	    *bufp = *fnamep;
10322 	    if (*fnamep == NULL)
10323 		return -1;
10324 	}
10325 
10326 	/* When "/." or "/.." is used: force expansion to get rid of it. */
10327 	for (p = *fnamep; *p != NUL; ++p)
10328 	{
10329 	    if (vim_ispathsep(*p)
10330 		    && p[1] == '.'
10331 		    && (p[2] == NUL
10332 			|| vim_ispathsep(p[2])
10333 			|| (p[2] == '.'
10334 			    && (p[3] == NUL || vim_ispathsep(p[3])))))
10335 		break;
10336 	}
10337 
10338 	/* FullName_save() is slow, don't use it when not needed. */
10339 	if (*p != NUL || !vim_isAbsName(*fnamep))
10340 	{
10341 	    *fnamep = FullName_save(*fnamep, *p != NUL);
10342 	    vim_free(*bufp);	/* free any allocated file name */
10343 	    *bufp = *fnamep;
10344 	    if (*fnamep == NULL)
10345 		return -1;
10346 	}
10347 
10348 	/* Append a path separator to a directory. */
10349 	if (mch_isdir(*fnamep))
10350 	{
10351 	    /* Make room for one or two extra characters. */
10352 	    *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2);
10353 	    vim_free(*bufp);	/* free any allocated file name */
10354 	    *bufp = *fnamep;
10355 	    if (*fnamep == NULL)
10356 		return -1;
10357 	    add_pathsep(*fnamep);
10358 	}
10359     }
10360 
10361     /* ":." - path relative to the current directory */
10362     /* ":~" - path relative to the home directory */
10363     /* ":8" - shortname path - postponed till after */
10364     while (src[*usedlen] == ':'
10365 		  && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8'))
10366     {
10367 	*usedlen += 2;
10368 	if (c == '8')
10369 	{
10370 #ifdef WIN3264
10371 	    has_shortname = 1; /* Postpone this. */
10372 #endif
10373 	    continue;
10374 	}
10375 	pbuf = NULL;
10376 	/* Need full path first (use expand_env() to remove a "~/") */
10377 	if (!has_fullname)
10378 	{
10379 	    if (c == '.' && **fnamep == '~')
10380 		p = pbuf = expand_env_save(*fnamep);
10381 	    else
10382 		p = pbuf = FullName_save(*fnamep, FALSE);
10383 	}
10384 	else
10385 	    p = *fnamep;
10386 
10387 	has_fullname = 0;
10388 
10389 	if (p != NULL)
10390 	{
10391 	    if (c == '.')
10392 	    {
10393 		mch_dirname(dirname, MAXPATHL);
10394 		s = shorten_fname(p, dirname);
10395 		if (s != NULL)
10396 		{
10397 		    *fnamep = s;
10398 		    if (pbuf != NULL)
10399 		    {
10400 			vim_free(*bufp);   /* free any allocated file name */
10401 			*bufp = pbuf;
10402 			pbuf = NULL;
10403 		    }
10404 		}
10405 	    }
10406 	    else
10407 	    {
10408 		home_replace(NULL, p, dirname, MAXPATHL, TRUE);
10409 		/* Only replace it when it starts with '~' */
10410 		if (*dirname == '~')
10411 		{
10412 		    s = vim_strsave(dirname);
10413 		    if (s != NULL)
10414 		    {
10415 			*fnamep = s;
10416 			vim_free(*bufp);
10417 			*bufp = s;
10418 		    }
10419 		}
10420 	    }
10421 	    vim_free(pbuf);
10422 	}
10423     }
10424 
10425     tail = gettail(*fnamep);
10426     *fnamelen = (int)STRLEN(*fnamep);
10427 
10428     /* ":h" - head, remove "/file_name", can be repeated  */
10429     /* Don't remove the first "/" or "c:\" */
10430     while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h')
10431     {
10432 	valid |= VALID_HEAD;
10433 	*usedlen += 2;
10434 	s = get_past_head(*fnamep);
10435 	while (tail > s && vim_ispathsep(tail[-1]))
10436 	    --tail;
10437 	*fnamelen = (int)(tail - *fnamep);
10438 #ifdef VMS
10439 	if (*fnamelen > 0)
10440 	    *fnamelen += 1; /* the path separator is part of the path */
10441 #endif
10442 	while (tail > s && !vim_ispathsep(tail[-1]))
10443 	    --tail;
10444     }
10445 
10446     /* ":8" - shortname  */
10447     if (src[*usedlen] == ':' && src[*usedlen + 1] == '8')
10448     {
10449 	*usedlen += 2;
10450 #ifdef WIN3264
10451 	has_shortname = 1;
10452 #endif
10453     }
10454 
10455 #ifdef WIN3264
10456     /* Check shortname after we have done 'heads' and before we do 'tails'
10457      */
10458     if (has_shortname)
10459     {
10460 	pbuf = NULL;
10461 	/* Copy the string if it is shortened by :h */
10462 	if (*fnamelen < (int)STRLEN(*fnamep))
10463 	{
10464 	    p = vim_strnsave(*fnamep, *fnamelen);
10465 	    if (p == 0)
10466 		return -1;
10467 	    vim_free(*bufp);
10468 	    *bufp = *fnamep = p;
10469 	}
10470 
10471 	/* Split into two implementations - makes it easier.  First is where
10472 	 * there isn't a full name already, second is where there is.
10473 	 */
10474 	if (!has_fullname && !vim_isAbsName(*fnamep))
10475 	{
10476 	    if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1)
10477 		return -1;
10478 	}
10479 	else
10480 	{
10481 	    int		l;
10482 
10483 	    /* Simple case, already have the full-name
10484 	     * Nearly always shorter, so try first time. */
10485 	    l = *fnamelen;
10486 	    if (!get_short_pathname(fnamep, bufp, &l))
10487 		return -1;
10488 
10489 	    if (l == 0)
10490 	    {
10491 		/* Couldn't find the filename.. search the paths.
10492 		 */
10493 		l = *fnamelen;
10494 		if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1)
10495 		    return -1;
10496 	    }
10497 	    *fnamelen = l;
10498 	}
10499     }
10500 #endif /* WIN3264 */
10501 
10502     /* ":t" - tail, just the basename */
10503     if (src[*usedlen] == ':' && src[*usedlen + 1] == 't')
10504     {
10505 	*usedlen += 2;
10506 	*fnamelen -= (int)(tail - *fnamep);
10507 	*fnamep = tail;
10508     }
10509 
10510     /* ":e" - extension, can be repeated */
10511     /* ":r" - root, without extension, can be repeated */
10512     while (src[*usedlen] == ':'
10513 	    && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r'))
10514     {
10515 	/* find a '.' in the tail:
10516 	 * - for second :e: before the current fname
10517 	 * - otherwise: The last '.'
10518 	 */
10519 	if (src[*usedlen + 1] == 'e' && *fnamep > tail)
10520 	    s = *fnamep - 2;
10521 	else
10522 	    s = *fnamep + *fnamelen - 1;
10523 	for ( ; s > tail; --s)
10524 	    if (s[0] == '.')
10525 		break;
10526 	if (src[*usedlen + 1] == 'e')		/* :e */
10527 	{
10528 	    if (s > tail)
10529 	    {
10530 		*fnamelen += (int)(*fnamep - (s + 1));
10531 		*fnamep = s + 1;
10532 #ifdef VMS
10533 		/* cut version from the extension */
10534 		s = *fnamep + *fnamelen - 1;
10535 		for ( ; s > *fnamep; --s)
10536 		    if (s[0] == ';')
10537 			break;
10538 		if (s > *fnamep)
10539 		    *fnamelen = s - *fnamep;
10540 #endif
10541 	    }
10542 	    else if (*fnamep <= tail)
10543 		*fnamelen = 0;
10544 	}
10545 	else				/* :r */
10546 	{
10547 	    if (s > tail)	/* remove one extension */
10548 		*fnamelen = (int)(s - *fnamep);
10549 	}
10550 	*usedlen += 2;
10551     }
10552 
10553     /* ":s?pat?foo?" - substitute */
10554     /* ":gs?pat?foo?" - global substitute */
10555     if (src[*usedlen] == ':'
10556 	    && (src[*usedlen + 1] == 's'
10557 		|| (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's')))
10558     {
10559 	char_u	    *str;
10560 	char_u	    *pat;
10561 	char_u	    *sub;
10562 	int	    sep;
10563 	char_u	    *flags;
10564 	int	    didit = FALSE;
10565 
10566 	flags = (char_u *)"";
10567 	s = src + *usedlen + 2;
10568 	if (src[*usedlen + 1] == 'g')
10569 	{
10570 	    flags = (char_u *)"g";
10571 	    ++s;
10572 	}
10573 
10574 	sep = *s++;
10575 	if (sep)
10576 	{
10577 	    /* find end of pattern */
10578 	    p = vim_strchr(s, sep);
10579 	    if (p != NULL)
10580 	    {
10581 		pat = vim_strnsave(s, (int)(p - s));
10582 		if (pat != NULL)
10583 		{
10584 		    s = p + 1;
10585 		    /* find end of substitution */
10586 		    p = vim_strchr(s, sep);
10587 		    if (p != NULL)
10588 		    {
10589 			sub = vim_strnsave(s, (int)(p - s));
10590 			str = vim_strnsave(*fnamep, *fnamelen);
10591 			if (sub != NULL && str != NULL)
10592 			{
10593 			    *usedlen = (int)(p + 1 - src);
10594 			    s = do_string_sub(str, pat, sub, flags);
10595 			    if (s != NULL)
10596 			    {
10597 				*fnamep = s;
10598 				*fnamelen = (int)STRLEN(s);
10599 				vim_free(*bufp);
10600 				*bufp = s;
10601 				didit = TRUE;
10602 			    }
10603 			}
10604 			vim_free(sub);
10605 			vim_free(str);
10606 		    }
10607 		    vim_free(pat);
10608 		}
10609 	    }
10610 	    /* after using ":s", repeat all the modifiers */
10611 	    if (didit)
10612 		goto repeat;
10613 	}
10614     }
10615 
10616     return valid;
10617 }
10618 
10619 /*
10620  * Perform a substitution on "str" with pattern "pat" and substitute "sub".
10621  * "flags" can be "g" to do a global substitute.
10622  * Returns an allocated string, NULL for error.
10623  */
10624     char_u *
10625 do_string_sub(str, pat, sub, flags)
10626     char_u	*str;
10627     char_u	*pat;
10628     char_u	*sub;
10629     char_u	*flags;
10630 {
10631     int		sublen;
10632     regmatch_T	regmatch;
10633     int		i;
10634     int		do_all;
10635     char_u	*tail;
10636     garray_T	ga;
10637     char_u	*ret;
10638     char_u	*save_cpo;
10639 
10640     /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */
10641     save_cpo = p_cpo;
10642     p_cpo = (char_u *)"";
10643 
10644     ga_init2(&ga, 1, 200);
10645 
10646     do_all = (flags[0] == 'g');
10647 
10648     regmatch.rm_ic = p_ic;
10649     regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
10650     if (regmatch.regprog != NULL)
10651     {
10652 	tail = str;
10653 	while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
10654 	{
10655 	    /*
10656 	     * Get some space for a temporary buffer to do the substitution
10657 	     * into.  It will contain:
10658 	     * - The text up to where the match is.
10659 	     * - The substituted text.
10660 	     * - The text after the match.
10661 	     */
10662 	    sublen = vim_regsub(&regmatch, sub, tail, FALSE, TRUE, FALSE);
10663 	    if (ga_grow(&ga, (int)(STRLEN(tail) + sublen -
10664 			    (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
10665 	    {
10666 		ga_clear(&ga);
10667 		break;
10668 	    }
10669 
10670 	    /* copy the text up to where the match is */
10671 	    i = (int)(regmatch.startp[0] - tail);
10672 	    mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
10673 	    /* add the substituted text */
10674 	    (void)vim_regsub(&regmatch, sub, (char_u *)ga.ga_data
10675 					  + ga.ga_len + i, TRUE, TRUE, FALSE);
10676 	    ga.ga_len += i + sublen - 1;
10677 	    ga.ga_room -= i + sublen - 1;
10678 	    /* avoid getting stuck on a match with an empty string */
10679 	    if (tail == regmatch.endp[0])
10680 	    {
10681 		if (*tail == NUL)
10682 		    break;
10683 		*((char_u *)ga.ga_data + ga.ga_len) = *tail++;
10684 		++ga.ga_len;
10685 		--ga.ga_room;
10686 	    }
10687 	    else
10688 	    {
10689 		tail = regmatch.endp[0];
10690 		if (*tail == NUL)
10691 		    break;
10692 	    }
10693 	    if (!do_all)
10694 		break;
10695 	}
10696 
10697 	if (ga.ga_data != NULL)
10698 	    STRCPY((char *)ga.ga_data + ga.ga_len, tail);
10699 
10700 	vim_free(regmatch.regprog);
10701     }
10702 
10703     ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
10704     ga_clear(&ga);
10705     p_cpo = save_cpo;
10706 
10707     return ret;
10708 }
10709 
10710 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */
10711