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