home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / src / eval.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-05-30  |  218.2 KB  |  10,244 lines

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