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