eval.c
上传用户:gddssl
上传日期:2007-01-06
资源大小:1003k
文件大小:93k
源码类别:

编辑器/阅读器

开发平台:

DOS

  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.  */
  8. /*
  9.  * eval.c: Expression evaluation.
  10.  */
  11. #include "vim.h"
  12. #ifdef HAVE_FCNTL_H
  13. # include <fcntl.h> /* contains setenv() declaration for Amiga */
  14. #endif
  15. #ifdef AMIGA
  16. # include <time.h> /* for strftime() */
  17. #endif
  18. #ifdef WANT_EVAL
  19. /*
  20.  * Structure to hold an internal variable.
  21.  */
  22. typedef struct
  23. {
  24.     char_u *var_name; /* name of variable */
  25.     char var_type; /* VAR_NUMBER or VAR_STRING */
  26.     union
  27.     {
  28. #if SIZEOF_INT <= 3 /* use long if int is smaller than 32 bits */
  29. long var_number; /* number value */
  30. #else
  31. int var_number; /* number value */
  32. #endif
  33. char_u *var_string; /* string value (Careful: can be NULL!) */
  34.     } var_val;
  35. } var;
  36. #define VAR_UNKNOWN 0
  37. #define VAR_NUMBER  1
  38. #define VAR_STRING  2
  39. typedef var * VAR;
  40. /*
  41.  * All user-defined internal variables are stored in "variables".
  42.  */
  43. struct growarray    variables = {0, 0, sizeof(var), 4, NULL};
  44. #define VAR_ENTRY(idx) (((VAR)(variables.ga_data))[idx])
  45. #define VAR_GAP_ENTRY(idx, gap) (((VAR)(gap->ga_data))[idx])
  46. #define BVAR_ENTRY(idx) (((VAR)(curbuf->b_vars.ga_data))[idx])
  47. #define WVAR_ENTRY(idx) (((VAR)(curwin->w_vars.ga_data))[idx])
  48. static int echo_attr = 0;   /* attributes used for ":echo" */
  49. /*
  50.  * Structure to hold info for a user function.
  51.  */
  52. struct ufunc
  53. {
  54.     struct ufunc *next; /* next function in list */
  55.     char_u *name; /* name of function */
  56.     int varargs; /* variable nr of arguments */
  57.     int flags;
  58.     struct growarray args; /* arguments */
  59.     struct growarray lines; /* function lines */
  60. };
  61. /* function flags */
  62. #define FC_ABORT    1 /* abort function on error */
  63. #define FC_RANGE    2 /* function accepts range */
  64. /*
  65.  * All user-defined functions are found in the forward-linked function list.
  66.  * The first function is pointed at by firstfunc.
  67.  */
  68. struct ufunc     *firstfunc = NULL;
  69. #define FUNCARG(fp, j) ((char_u **)(fp->args.ga_data))[j]
  70. #define FUNCLINE(fp, j) ((char_u **)(fp->lines.ga_data))[j]
  71. /* structure to hold info for a function that is currently being executed. */
  72. struct funccall
  73. {
  74.     struct ufunc *func; /* function being called */
  75.     int linenr; /* next line to be executed */
  76.     int argcount; /* nr of arguments */
  77.     VAR argvars; /* arguments */
  78.     var a0_var; /* "a:0" variable */
  79.     var firstline; /* "a:firstline" variable */
  80.     var lastline; /* "a:lastline" variable */
  81.     struct growarray l_vars; /* local function variables */
  82.     VAR retvar; /* return value variable */
  83. };
  84. /* pointer to funccal for currently active function */
  85. struct funccall *current_funccal = NULL;
  86. static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name));
  87. static int eval0 __ARGS((char_u *arg,  VAR retvar, char_u **nextcmd));
  88. static int eval1 __ARGS((char_u **arg, VAR retvar));
  89. static int eval2 __ARGS((char_u **arg, VAR retvar));
  90. static int eval3 __ARGS((char_u **arg, VAR retvar));
  91. static int eval4 __ARGS((char_u **arg, VAR retvar));
  92. static int eval5 __ARGS((char_u **arg, VAR retvar));
  93. static int eval6 __ARGS((char_u **arg, VAR retvar));
  94. static int get_option_var __ARGS((char_u **arg, VAR retvar));
  95. static int get_string_var __ARGS((char_u **arg, VAR retvar));
  96. static int get_lit_string_var __ARGS((char_u **arg, VAR retvar));
  97. static int get_env_var __ARGS((char_u **arg, VAR retvar));
  98. static int get_func_var __ARGS((char_u *name, int len, VAR retvar, char_u **arg, linenr_t firstline, linenr_t lastline, int *doesrange));
  99. static void f_argc __ARGS((VAR argvars, VAR retvar));
  100. static void f_argv __ARGS((VAR argvars, VAR retvar));
  101. static void f_browse __ARGS((VAR argvars, VAR retvar));
  102. static void f_bufexists __ARGS((VAR argvars, VAR retvar));
  103. static BUF *get_buf_var __ARGS((VAR avar));
  104. static void f_bufname __ARGS((VAR argvars, VAR retvar));
  105. static void f_bufnr __ARGS((VAR argvars, VAR retvar));
  106. static void f_char2nr __ARGS((VAR argvars, VAR retvar));
  107. static void f_col __ARGS((VAR argvars, VAR retvar));
  108. static void f_confirm __ARGS((VAR argvars, VAR retvar));
  109. static void f_delete __ARGS((VAR argvars, VAR retvar));
  110. static void f_escape __ARGS((VAR argvars, VAR retvar));
  111. static void f_exists __ARGS((VAR argvars, VAR retvar));
  112. static void f_expand __ARGS((VAR argvars, VAR retvar));
  113. static void f_filereadable __ARGS((VAR argvars, VAR retvar));
  114. static void f_fnamemodify __ARGS((VAR argvars, VAR retvar));
  115. static void f_getcwd __ARGS((VAR argvars, VAR retvar));
  116. static void f_getline __ARGS((VAR argvars, VAR retvar));
  117. static void f_has __ARGS((VAR argvars, VAR retvar));
  118. static void f_hlexists __ARGS((VAR argvars, VAR retvar));
  119. static void f_hlID __ARGS((VAR argvars, VAR retvar));
  120. static void f_hostname __ARGS((VAR argvars, VAR retvar));
  121. static void f_isdirectory __ARGS((VAR argvars, VAR retvar));
  122. static void f_input __ARGS((VAR argvars, VAR retvar));
  123. static void f_last_buffer_nr __ARGS((VAR argvars, VAR retvar));
  124. static void f_line __ARGS((VAR argvars, VAR retvar));
  125. static void f_match __ARGS((VAR argvars, VAR retvar));
  126. static void f_matchend __ARGS((VAR argvars, VAR retvar));
  127. static void f_matchstr __ARGS((VAR argvars, VAR retvar));
  128. static void f_nr2char __ARGS((VAR argvars, VAR retvar));
  129. static void f_setline __ARGS((VAR argvars, VAR retvar));
  130. static void f_some_match __ARGS((VAR argvars, VAR retvar, int start));
  131. static void f_strftime __ARGS((VAR argvars, VAR retvar));
  132. static void f_strlen __ARGS((VAR argvars, VAR retvar));
  133. static void f_strpart __ARGS((VAR argvars, VAR retvar));
  134. static void f_synID __ARGS((VAR argvars, VAR retvar));
  135. static void f_synIDattr __ARGS((VAR argvars, VAR retvar));
  136. static void f_synIDtrans __ARGS((VAR argvars, VAR retvar));
  137. static void f_substitute __ARGS((VAR argvars, VAR retvar));
  138. static void f_tempname __ARGS((VAR argvars, VAR retvar));
  139. static void f_virtcol __ARGS((VAR argvars, VAR retvar));
  140. static void f_winbufnr __ARGS((VAR argvars, VAR retvar));
  141. static void f_winheight __ARGS((VAR argvars, VAR retvar));
  142. static void f_winnr __ARGS((VAR argvars, VAR retvar));
  143. static WIN *find_win_by_nr __ARGS((VAR vp));
  144. static FPOS *var2fpos __ARGS((VAR varp));
  145. static int get_env_len __ARGS((char_u **arg));
  146. char_u *get_env_string __ARGS((char_u **arg));
  147. static int get_id_len __ARGS((char_u **arg));
  148. static int eval_isnamec __ARGS((int c));
  149. static int get_var_var __ARGS((char_u *name, int len, VAR retvar));
  150. static VAR alloc_var __ARGS((void));
  151. static VAR alloc_string_var __ARGS((char_u *string));
  152. static void free_var __ARGS((VAR varp));
  153. static void clear_var __ARGS((VAR varp));
  154. static long get_var_number __ARGS((VAR varp));
  155. static char_u *get_var_string __ARGS((VAR varp));
  156. static char_u *get_var_string_buf __ARGS((VAR varp, char_u *buf));
  157. static VAR find_var __ARGS((char_u *name, int writing));
  158. static struct growarray *find_var_ga __ARGS((char_u *name, char_u **varname));
  159. static void var_free_one __ARGS((VAR v));
  160. static void list_one_var __ARGS((VAR v, char_u *prefix));
  161. static void set_var __ARGS((char_u *name, VAR varp));
  162. static char_u *find_option_end __ARGS((char_u *p));
  163. static void list_func_head __ARGS((struct ufunc *fp));
  164. static struct ufunc *find_func __ARGS((char_u *name));
  165. static void call_func __ARGS((struct ufunc *fp, int argcount, VAR argvars, VAR retvar, linenr_t firstline, linenr_t lastline));
  166. /*
  167.  * Set an internal variable to a string value. Creates the variable if it does
  168.  * not already exist.
  169.  */
  170.     void
  171. set_internal_string_var(name, value)
  172.     char_u *name;
  173.     char_u *value;
  174. {
  175.     char_u  *val;
  176.     VAR     varp;
  177.     val = vim_strsave(value);
  178.     if (val != NULL)
  179.     {
  180. varp = alloc_string_var(val);
  181. if (varp != NULL)
  182. {
  183.     set_var(name, varp);
  184.     free_var(varp);
  185. }
  186.     }
  187. }
  188. /*
  189.  * Top level evaluation function, returning a boolean.
  190.  * Sets "error" to TRUE if there was an error.
  191.  * Return TRUE or FALSE.
  192.  */
  193.     int
  194. eval_to_bool(arg, error, nextcmd)
  195.     char_u *arg;
  196.     int *error;
  197.     char_u **nextcmd;
  198. {
  199.     var retvar;
  200.     int retval;
  201.     if (eval0(arg, &retvar, nextcmd) == FAIL)
  202.     {
  203. *error = TRUE;
  204. retval = FALSE;
  205.     }
  206.     else
  207.     {
  208. *error = FALSE;
  209. retval = (get_var_number(&retvar) != 0);
  210. clear_var(&retvar);
  211.     }
  212.     return retval;
  213. }
  214. /*
  215.  * Top level evaluation function, returning a string.
  216.  * Return pointer to allocated memory, or NULL for failure.
  217.  */
  218.     char_u *
  219. eval_to_string(arg, nextcmd)
  220.     char_u *arg;
  221.     char_u **nextcmd;
  222. {
  223.     var retvar;
  224.     char_u *retval;
  225.     if (eval0(arg, &retvar, nextcmd) == FAIL)
  226. retval = NULL;
  227.     else
  228.     {
  229. retval = vim_strsave(get_var_string(&retvar));
  230. clear_var(&retvar);
  231.     }
  232.     return retval;
  233. }
  234. /*
  235.  * ":let var = expr" assignment command.
  236.  * ":let var" list one variable value
  237.  * ":let" list all variable values
  238.  */
  239.     void
  240. do_let(eap)
  241.     EXARG *eap;
  242. {
  243.     char_u *arg = eap->arg;
  244.     char_u *expr;
  245.     char_u *name;
  246.     VAR varp;
  247.     var retvar;
  248.     char_u *p;
  249.     int c1, c2;
  250.     int i;
  251. #ifndef HAVE_SETENV
  252.     char_u *envbuf;
  253. #endif
  254.     expr = vim_strchr(arg, '=');
  255.     if (expr == NULL)
  256.     {
  257. if (ends_excmd(*arg))
  258. {
  259.     if (!eap->skip)
  260.     {
  261. /*
  262.  * List all variables.
  263.  */
  264. for (i = 0; i < variables.ga_len; ++i)
  265.     if (VAR_ENTRY(i).var_name != NULL)
  266. list_one_var(&VAR_ENTRY(i), (char_u *)"");
  267. for (i = 0; i < curbuf->b_vars.ga_len; ++i)
  268.     if (BVAR_ENTRY(i).var_name != NULL)
  269. list_one_var(&BVAR_ENTRY(i), (char_u *)"b:");
  270. for (i = 0; i < curwin->w_vars.ga_len; ++i)
  271.     if (WVAR_ENTRY(i).var_name != NULL)
  272. list_one_var(&WVAR_ENTRY(i), (char_u *)"w:");
  273.     }
  274. }
  275. else
  276. {
  277.     /*
  278.      * List variables.
  279.      */
  280.     while (!ends_excmd(*arg))
  281.     {
  282. for (p = arg; eval_isnamec(*p); ++p)
  283.     ;
  284. if (!vim_iswhite(*p) && !ends_excmd(*p))
  285. {
  286.     EMSG(e_trailing);
  287.     break;
  288. }
  289. if (!eap->skip)
  290. {
  291.     c1 = *p;
  292.     *p = NUL;
  293.     varp = find_var(arg, FALSE);
  294.     if (varp == NULL)
  295. EMSG2("Unknown variable: "%s"", arg);
  296.     else
  297.     {
  298. name = vim_strchr(arg, ':');
  299. if (name != NULL)
  300. {
  301.     c2 = *++name;
  302.     *name = NUL;
  303.     list_one_var(varp, arg);
  304.     *name = c2;
  305. }
  306. else
  307.     list_one_var(varp, (char_u *)"");
  308.     }
  309.     *p = c1;
  310. }
  311. arg = skipwhite(p);
  312.     }
  313. }
  314. eap->nextcmd = check_nextcmd(arg);
  315.     }
  316.     else
  317.     {
  318. if (eap->skip)
  319.     ++emsg_off;
  320. i = eval0(expr + 1, &retvar, &eap->nextcmd);
  321. if (eap->skip)
  322. {
  323.     if (i != FAIL)
  324. clear_var(&retvar);
  325.     --emsg_off;
  326. }
  327. else if (i != FAIL)
  328. {
  329.     /*
  330.      * ":let $VAR = expr": Set environment variable.
  331.      */
  332.     if (*arg == '$')
  333.     {
  334. int len;
  335. int cc;
  336. /* Find the end of the name. */
  337. ++arg;
  338. name = arg;
  339. len = get_env_len(&arg);
  340. if (name != NULL)
  341. {
  342.     if (*skipwhite(arg) != '=')
  343. EMSG(e_letunexp);
  344.     else
  345.     {
  346. cc = name[len];
  347. name[len] = NUL;
  348. p = get_var_string(&retvar);
  349. #ifdef HAVE_SETENV
  350. mch_setenv((char *)name, (char *)p, 1);
  351. #else
  352. /*
  353.  * Putenv does not copy the string, it has to remain
  354.  * valid.  The allocated memory will never be freed.
  355.  */
  356. envbuf = alloc((unsigned)(STRLEN(p) +
  357.    STRLEN(name) + 2));
  358. if (envbuf != NULL)
  359. {
  360.     sprintf((char *)envbuf, "%s=%s", name, p);
  361.     putenv((char *)envbuf);
  362. }
  363. #endif
  364. if (STRICMP(name, "home") == 0)
  365.     init_homedir();
  366. name[len] = cc;
  367.     }
  368. }
  369.     }
  370.     /*
  371.      * ":let &option = expr": Set option value.
  372.      */
  373.     else if (*arg == '&')
  374.     {
  375. /*
  376.  * Find the end of the name;
  377.  */
  378. ++arg;
  379. p = find_option_end(arg);
  380. if (*skipwhite(p) != '=')
  381.     EMSG(e_letunexp);
  382. else
  383. {
  384.     c1 = *p;
  385.     *p = NUL;
  386.     set_option_value(arg, get_var_number(&retvar),
  387.      get_var_string(&retvar));
  388.     *p = c1;     /* put back for error messages */
  389. }
  390.     }
  391.     /*
  392.      * ":let @r = expr": Set register contents.
  393.      */
  394.     else if (*arg == '@')
  395.     {
  396. ++arg;
  397. if (*skipwhite(arg + 1) != '=')
  398.     EMSG(e_letunexp);
  399. else
  400.     write_reg_contents(*arg == '@' ? '"' : *arg,
  401.      get_var_string(&retvar));
  402.     }
  403.     /*
  404.      * ":let var = expr": Set internal variable.
  405.      */
  406.     else if (eval_isnamec(*arg) && !isdigit(*arg))
  407.     {
  408. /*
  409.  * Find the end of the name;
  410.  */
  411. for (p = arg; eval_isnamec(*p); ++p)
  412.     ;
  413. if (*skipwhite(p) != '=')
  414.     EMSG(e_letunexp);
  415. else
  416. {
  417.     c1 = *p;
  418.     *p = NUL;
  419.     set_var(arg, &retvar);
  420.     *p = c1; /* put char back for error messages */
  421. }
  422.     }
  423.     else
  424.     {
  425. EMSG2(e_invarg2, arg);
  426.     }
  427.     clear_var(&retvar);
  428. }
  429.     }
  430. }
  431. /*
  432.  * ":1,25call func(arg1, arg2)" function call.
  433.  */
  434.     void
  435. do_call(eap)
  436.     EXARG *eap;
  437. {
  438.     char_u *arg = eap->arg;
  439.     char_u *startarg;
  440.     char_u *name;
  441.     var retvar;
  442.     int len;
  443.     linenr_t lnum;
  444.     int doesrange;
  445.     name = arg;
  446.     len = get_id_len(&arg);
  447.     startarg = arg;
  448.     if (*startarg != '(')
  449.     {
  450. EMSG2("Missing braces: %s", name);
  451. return;
  452.     }
  453.     /*
  454.      * When skipping, evaluate the function once, to find the end of the
  455.      * arguments.
  456.      * When the function takes a range, this is discovered after the first
  457.      * call, and the loop is broken.
  458.      */
  459.     if (eap->skip)
  460. ++emsg_off;
  461.     for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
  462.     {
  463. if (!eap->skip && eap->line1 != eap->line2)
  464. {
  465.     curwin->w_cursor.lnum = lnum;
  466.     curwin->w_cursor.col = 0;
  467. }
  468. arg = startarg;
  469. if (get_func_var(name, len, &retvar, &arg,
  470.   eap->line1, eap->line2, &doesrange) == FAIL)
  471.     break;
  472. clear_var(&retvar);
  473. if (doesrange || eap->skip)
  474.     break;
  475.     }
  476.     if (eap->skip)
  477. --emsg_off;
  478.     eap->nextcmd = check_nextcmd(arg);
  479. }
  480. /*
  481.  * ":unlet[!] var1 ... " command.
  482.  */
  483.     void
  484. do_unlet(arg, forceit)
  485.     char_u *arg;
  486.     int forceit;
  487. {
  488.     char_u *name_end;
  489.     VAR v;
  490.     char_u cc;
  491.     do
  492.     {
  493. name_end = skiptowhite(arg);
  494. cc = *name_end;
  495. *name_end = NUL;
  496. v = find_var(arg, TRUE);
  497. if (v != NULL)     /* existing variable, may need to free string */
  498.     var_free_one(v);
  499. else if (!forceit)  /* non-existing variable */
  500. {
  501.     *name_end = cc;
  502.     EMSG2("No such variable: "%s"", arg);
  503.     break;
  504. }
  505. *name_end = cc;
  506. arg = skipwhite(name_end);
  507.     } while (*arg != NUL);
  508. }
  509. /*
  510.  * Local string buffer for the next two functions to store a variable name
  511.  * with its prefix. Allocated in cat_prefix_varname(), freed later in
  512.  * get_user_var_name().
  513.  */
  514. static char_u *varnamebuf = NULL;
  515. static int varnamebuflen = 0;
  516. /*
  517.  * Function to concatenate a prefix and a variable name.
  518.  * TODO: Use string instead of char for 'prefix' when allowing 'b3:' like vars.
  519.  */
  520.     static char_u *
  521. cat_prefix_varname(prefix, name)
  522.     int prefix;
  523.     char_u *name;
  524. {
  525.     int len;
  526.     len = STRLEN( name ) + 3;
  527.     if ( len > varnamebuflen )
  528.     {
  529. vim_free(varnamebuf);
  530. len += 10; /* some additional space */
  531. varnamebuf = alloc(len);
  532. if (varnamebuf)
  533.     varnamebuflen = len;
  534. else
  535. {
  536.     varnamebuflen = 0;
  537.     return NULL;
  538. }
  539.     }
  540.     *varnamebuf = prefix;
  541.     varnamebuf[1] = ':';
  542.     STRCPY(varnamebuf+2, name);
  543.     return varnamebuf;
  544. }
  545. /*
  546.  * Function given to ExpandGeneric() to obtain the list of user defined
  547.  * (global/buffer/window) variable names.
  548.  */
  549.     char_u *
  550. get_user_var_name(idx)
  551.     int     idx;
  552. {
  553.     if (idx < variables.ga_len) /* Global variables */
  554. return VAR_ENTRY(idx).var_name;
  555. /* Current buffer variables */
  556.     else if ((idx -= variables.ga_len) < curbuf->b_vars.ga_len)
  557. return cat_prefix_varname('b', BVAR_ENTRY(idx).var_name);
  558. /* Current window variables */
  559.     else if ((idx -= curbuf->b_vars.ga_len) < curwin->w_vars.ga_len)
  560. return cat_prefix_varname('w', WVAR_ENTRY(idx).var_name);
  561.     else
  562.     {
  563. vim_free(varnamebuf);
  564. varnamebuf = NULL;
  565. varnamebuflen = 0;
  566. return NULL;
  567.     }
  568. }
  569. /*
  570.  * types for expressions.
  571.  */
  572. enum exp_type
  573. {
  574.     TYPE_UNKNOWN = 0,
  575.     TYPE_EQUAL, /* == */
  576.     TYPE_NEQUAL, /* != */
  577.     TYPE_GREATER, /* >  */
  578.     TYPE_GEQUAL, /* >= */
  579.     TYPE_SMALLER, /* <  */
  580.     TYPE_SEQUAL, /* <= */
  581.     TYPE_MATCH, /* =~ */
  582.     TYPE_NOMATCH /* !~ */
  583. };
  584. /*
  585.  * Handle zero level expression.
  586.  * This calls eval1() and handles error message and nextcmd.
  587.  * Return OK or FAIL.
  588.  */
  589.     static int
  590. eval0(arg, retvar, nextcmd)
  591.     char_u *arg;
  592.     VAR retvar;
  593.     char_u **nextcmd;
  594. {
  595.     int ret;
  596.     char_u *p;
  597.     p = skipwhite(arg);
  598.     ret = eval1(&p, retvar);
  599.     if (ret == FAIL || !ends_excmd(*p))
  600.     {
  601. if (ret != FAIL)
  602.     clear_var(retvar);
  603. EMSG2(e_invexpr2, arg);
  604. ret = FAIL;
  605.     }
  606.     if (nextcmd != NULL)
  607. *nextcmd = check_nextcmd(p);
  608.     return ret;
  609. }
  610. /*
  611.  * Handle first level expression:
  612.  * expr2 || expr2 || expr2     logical OR
  613.  *
  614.  * "arg" must point to the first non-white of the expression.
  615.  * "arg" is advanced to the next non-white after the recognized expression.
  616.  *
  617.  * Return OK or FAIL.
  618.  */
  619.     static int
  620. eval1(arg, retvar)
  621.     char_u **arg;
  622.     VAR retvar;
  623. {
  624.     var var2;
  625.     long n1, n2;
  626.     /*
  627.      * Get the first variable.
  628.      */
  629.     if (eval2(arg, retvar) == FAIL)
  630. return FAIL;
  631.     /*
  632.      * Repeat until there is no following "||".
  633.      */
  634.     while ((*arg)[0] == '|' && (*arg)[1] == '|')
  635.     {
  636. n1 = get_var_number(retvar);
  637. clear_var(retvar);
  638. /*
  639.  * Get the second variable.
  640.  */
  641. *arg = skipwhite(*arg + 2);
  642. if (eval2(arg, &var2) == FAIL)
  643.     return FAIL;
  644. /*
  645.  * Compute the result.
  646.  */
  647. n2 = get_var_number(&var2);
  648. clear_var(&var2);
  649. retvar->var_type = VAR_NUMBER;
  650. retvar->var_val.var_number = (n1 || n2);
  651.     }
  652.     return OK;
  653. }
  654. /*
  655.  * Handle second level expression:
  656.  * expr3 && expr3 && expr3     logical AND
  657.  *
  658.  * "arg" must point to the first non-white of the expression.
  659.  * "arg" is advanced to the next non-white after the recognized expression.
  660.  *
  661.  * Return OK or FAIL.
  662.  */
  663.     static int
  664. eval2(arg, retvar)
  665.     char_u **arg;
  666.     VAR retvar;
  667. {
  668.     var var2;
  669.     long n1, n2;
  670.     /*
  671.      * Get the first variable.
  672.      */
  673.     if (eval3(arg, retvar) == FAIL)
  674. return FAIL;
  675.     /*
  676.      * Repeat until there is no following "&&".
  677.      */
  678.     while ((*arg)[0] == '&' && (*arg)[1] == '&')
  679.     {
  680. n1 = get_var_number(retvar);
  681. clear_var(retvar);
  682. /*
  683.  * Get the second variable.
  684.  */
  685. *arg = skipwhite(*arg + 2);
  686. if (eval3(arg, &var2) == FAIL)
  687.     return FAIL;
  688. /*
  689.  * Compute the result.
  690.  */
  691. n2 = get_var_number(&var2);
  692. clear_var(&var2);
  693. retvar->var_type = VAR_NUMBER;
  694. retvar->var_val.var_number = (n1 && n2);
  695.     }
  696.     return OK;
  697. }
  698. /*
  699.  * Handle third level expression:
  700.  * var1 == var2
  701.  * var1 =~ var2
  702.  * var1 != var2
  703.  * var1 !~ var2
  704.  * var1 > var2
  705.  * var1 >= var2
  706.  * var1 < var2
  707.  * var1 <= var2
  708.  *
  709.  * "arg" must point to the first non-white of the expression.
  710.  * "arg" is advanced to the next non-white after the recognized expression.
  711.  *
  712.  * Return OK or FAIL.
  713.  */
  714.     static int
  715. eval3(arg, retvar)
  716.     char_u **arg;
  717.     VAR retvar;
  718. {
  719.     var var2;
  720.     char_u *p;
  721.     int i = 0;
  722.     enum exp_type type = TYPE_UNKNOWN;
  723.     int len = 2;
  724.     long n1 = FALSE, n2;
  725.     char_u *s1, *s2;
  726.     char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
  727.     vim_regexp *prog;
  728.     /*
  729.      * Get the first variable.
  730.      */
  731.     if (eval4(arg, retvar) == FAIL)
  732. return FAIL;
  733.     p = *arg;
  734.     switch (p[0])
  735.     {
  736. case '=':   if (p[1] == '=')
  737. type = TYPE_EQUAL;
  738.     else if (p[1] == '~')
  739. type = TYPE_MATCH;
  740.     break;
  741. case '!':   if (p[1] == '=')
  742. type = TYPE_NEQUAL;
  743.     else if (p[1] == '~')
  744. type = TYPE_NOMATCH;
  745.     break;
  746. case '>':   if (p[1] != '=')
  747.     {
  748. type = TYPE_GREATER;
  749. len = 1;
  750.     }
  751.     else
  752. type = TYPE_GEQUAL;
  753.     break;
  754. case '<':   if (p[1] != '=')
  755.     {
  756. type = TYPE_SMALLER;
  757. len = 1;
  758.     }
  759.     else
  760. type = TYPE_SEQUAL;
  761.     break;
  762.     }
  763.     /*
  764.      * If there is a comparitive operator, use it.
  765.      */
  766.     if (type != TYPE_UNKNOWN)
  767.     {
  768. /*
  769.  * Get the second variable.
  770.  */
  771. *arg = skipwhite(p + len);
  772. if (eval4(arg, &var2) == FAIL)
  773. {
  774.     clear_var(retvar);
  775.     return FAIL;
  776. }
  777. /*
  778.  * If one of the two variables is a number, compare as a number.
  779.  * When using "=~" or "!~", always compare as string.
  780.  */
  781. if ((retvar->var_type == VAR_NUMBER || var2.var_type == VAR_NUMBER)
  782. && type != TYPE_MATCH && type != TYPE_NOMATCH)
  783. {
  784.     n1 = get_var_number(retvar);
  785.     n2 = get_var_number(&var2);
  786.     switch (type)
  787.     {
  788. case TYPE_EQUAL:    n1 = (n1 == n2); break;
  789. case TYPE_NEQUAL:   n1 = (n1 != n2); break;
  790. case TYPE_GREATER:  n1 = (n1 > n2); break;
  791. case TYPE_GEQUAL:   n1 = (n1 >= n2); break;
  792. case TYPE_SMALLER:  n1 = (n1 < n2); break;
  793. case TYPE_SEQUAL:   n1 = (n1 <= n2); break;
  794. case TYPE_UNKNOWN:
  795. case TYPE_MATCH:
  796. case TYPE_NOMATCH:  break;  /* avoid gcc warning */
  797.     }
  798. }
  799. else
  800. {
  801.     s1 = get_var_string_buf(retvar, buf1);
  802.     s2 = get_var_string_buf(&var2, buf2);
  803.     if (type != TYPE_MATCH && type != TYPE_NOMATCH)
  804. i = STRCMP(s1, s2);
  805.     switch (type)
  806.     {
  807. case TYPE_EQUAL:    n1 = (i == 0); break;
  808. case TYPE_NEQUAL:   n1 = (i != 0); break;
  809. case TYPE_GREATER:  n1 = (i > 0); break;
  810. case TYPE_GEQUAL:   n1 = (i >= 0); break;
  811. case TYPE_SMALLER:  n1 = (i < 0); break;
  812. case TYPE_SEQUAL:   n1 = (i <= 0); break;
  813. case TYPE_MATCH:
  814. case TYPE_NOMATCH:  reg_ic = p_ic;
  815.     prog = vim_regcomp(s2, TRUE);
  816.     if (prog != NULL)
  817.     {
  818. n1 = vim_regexec(prog, s1, TRUE);
  819. vim_free(prog);
  820. if (type == TYPE_NOMATCH)
  821.     n1 = !n1;
  822.     }
  823.     break;
  824. case TYPE_UNKNOWN:  break;  /* avoid gcc warning */
  825.     }
  826. }
  827. clear_var(retvar);
  828. clear_var(&var2);
  829. retvar->var_type = VAR_NUMBER;
  830. retvar->var_val.var_number = n1;
  831.     }
  832.     return OK;
  833. }
  834. /*
  835.  * Handle fourth level expression:
  836.  * + number addition
  837.  * - number subtraction
  838.  * . string concatenation
  839.  *
  840.  * "arg" must point to the first non-white of the expression.
  841.  * "arg" is advanced to the next non-white after the recognized expression.
  842.  *
  843.  * Return OK or FAIL.
  844.  */
  845.     static int
  846. eval4(arg, retvar)
  847.     char_u **arg;
  848.     VAR retvar;
  849. {
  850.     var var2;
  851.     int op;
  852.     long n1, n2;
  853.     char_u *s1, *s2;
  854.     char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
  855.     char_u *p;
  856.     /*
  857.      * Get the first variable.
  858.      */
  859.     if (eval5(arg, retvar) == FAIL)
  860. return FAIL;
  861.     /*
  862.      * Repeat computing, until no '+', '-' or '.' is following.
  863.      */
  864.     for (;;)
  865.     {
  866. op = **arg;
  867. if (op != '+' && op != '-' && op != '.')
  868.     break;
  869. /*
  870.  * Get the second variable.
  871.  */
  872. *arg = skipwhite(*arg + 1);
  873. if (eval5(arg, &var2) == FAIL)
  874. {
  875.     clear_var(retvar);
  876.     return FAIL;
  877. }
  878. /*
  879.  * Compute the result.
  880.  */
  881. if (op == '.')
  882. {
  883.     s1 = get_var_string_buf(retvar, buf1);
  884.     s2 = get_var_string_buf(&var2, buf2);
  885.     p = alloc((unsigned)(STRLEN(s1) + STRLEN(s2) + 1));
  886.     if (p != NULL)
  887.     {
  888. STRCPY(p, s1);
  889. STRCAT(p, s2);
  890.     }
  891.     clear_var(retvar);
  892.     retvar->var_type = VAR_STRING;
  893.     retvar->var_val.var_string = p;
  894. }
  895. else
  896. {
  897.     n1 = get_var_number(retvar);
  898.     n2 = get_var_number(&var2);
  899.     clear_var(retvar);
  900.     if (op == '+')
  901. n1 = n1 + n2;
  902.     else
  903. n1 = n1 - n2;
  904.     retvar->var_type = VAR_NUMBER;
  905.     retvar->var_val.var_number = n1;
  906. }
  907. clear_var(&var2);
  908.     }
  909.     return OK;
  910. }
  911. /*
  912.  * Handle fifth level expression:
  913.  * * number multiplication
  914.  * / number division
  915.  * % number modulo
  916.  *
  917.  * "arg" must point to the first non-white of the expression.
  918.  * "arg" is advanced to the next non-white after the recognized expression.
  919.  *
  920.  * Return OK or FAIL.
  921.  */
  922.     static int
  923. eval5(arg, retvar)
  924.     char_u **arg;
  925.     VAR retvar;
  926. {
  927.     var var2;
  928.     int op;
  929.     long n1, n2;
  930.     /*
  931.      * Get the first variable.
  932.      */
  933.     if (eval6(arg, retvar) == FAIL)
  934. return FAIL;
  935.     /*
  936.      * Repeat computing, until no '*', '/' or '%' is following.
  937.      */
  938.     for (;;)
  939.     {
  940. op = **arg;
  941. if (op != '*' && op != '/' && op != '%')
  942.     break;
  943. n1 = get_var_number(retvar);
  944. clear_var(retvar);
  945. /*
  946.  * Get the second variable.
  947.  */
  948. *arg = skipwhite(*arg + 1);
  949. if (eval6(arg, &var2) == FAIL)
  950.     return FAIL;
  951. n2 = get_var_number(&var2);
  952. clear_var(&var2);
  953. /*
  954.  * Compute the result.
  955.  */
  956. if (op == '*')
  957.     n1 = n1 * n2;
  958. else if (op == '/')
  959. {
  960.     if (n2 == 0) /* give an error message? */
  961. n1 = 0x7fffffff;
  962.     else
  963. n1 = n1 / n2;
  964. }
  965. else
  966. {
  967.     if (n2 == 0) /* give an error message? */
  968. n1 = 0;
  969.     else
  970. n1 = n1 % n2;
  971. }
  972. retvar->var_type = VAR_NUMBER;
  973. retvar->var_val.var_number = n1;
  974.     }
  975.     return OK;
  976. }
  977. /*
  978.  * Handle sixth level expression:
  979.  *  number number constant
  980.  *  "string" string contstant
  981.  *  *option-name option value
  982.  *  @r register contents
  983.  *  identifier variable value
  984.  *  $VAR environment variable
  985.  *  (expression) nested expression
  986.  *
  987.  *  Also handle:
  988.  *  ! in front logical NOT
  989.  *  - in front unary minus
  990.  *  trailing [] subscript in String
  991.  *
  992.  * "arg" must point to the first non-white of the expression.
  993.  * "arg" is advanced to the next non-white after the recognized expression.
  994.  *
  995.  * Return OK or FAIL.
  996.  */
  997.     static int
  998. eval6(arg, retvar)
  999.     char_u **arg;
  1000.     VAR retvar;
  1001. {
  1002.     var var2;
  1003.     long n;
  1004.     int len;
  1005.     char_u *s;
  1006.     int val;
  1007.     char_u *start_leader, *end_leader;
  1008.     int ret = OK;
  1009.     /*
  1010.      * Skip '!' and '-' characters.  They are handled later.
  1011.      */
  1012.     start_leader = *arg;
  1013.     while (**arg == '!' || **arg == '-')
  1014. *arg = skipwhite(*arg + 1);
  1015.     end_leader = *arg;
  1016.     switch (**arg)
  1017.     {
  1018.     /*
  1019.      * Number constant.
  1020.      */
  1021.     case '0':
  1022.     case '1':
  1023.     case '2':
  1024.     case '3':
  1025.     case '4':
  1026.     case '5':
  1027.     case '6':
  1028.     case '7':
  1029.     case '8':
  1030.     case '9':
  1031. retvar->var_type = VAR_NUMBER;
  1032. vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL);
  1033. retvar->var_val.var_number = n;
  1034. *arg += len;
  1035. break;
  1036.     /*
  1037.      * String constant: "string".
  1038.      */
  1039.     case '"': ret = get_string_var(arg, retvar);
  1040. break;
  1041.     /*
  1042.      * Literal string constant: 'string'.
  1043.      */
  1044.     case ''': ret = get_lit_string_var(arg, retvar);
  1045. break;
  1046.     /*
  1047.      * Option value: &name
  1048.      */
  1049.     case '&': ret = get_option_var(arg, retvar);
  1050. break;
  1051.     /*
  1052.      * Environment variable: $VAR.
  1053.      */
  1054.     case '$': ret = get_env_var(arg, retvar);
  1055. break;
  1056.     /*
  1057.      * Register contents: @r.
  1058.      */
  1059.     case '@': retvar->var_type = VAR_STRING;
  1060. retvar->var_val.var_string = get_reg_contents(*++*arg);
  1061. if (**arg != NUL)
  1062.     ++*arg;
  1063. break;
  1064.     /*
  1065.      * nested expression: (expression).
  1066.      */
  1067.     case '(': *arg = skipwhite(*arg + 1);
  1068. ret = eval1(arg, retvar); /* recursive! */
  1069. if (**arg != ')')
  1070.     EMSG("Missing ')'");
  1071. else
  1072.     ++*arg;
  1073. break;
  1074.     /*
  1075.      * Must be a variable or function name then.
  1076.      */
  1077.     default: s = *arg;
  1078. len = get_id_len(arg);
  1079. if (len)
  1080. {
  1081.     if (**arg == '(') /* recursive! */
  1082. ret = get_func_var(s, len, retvar, arg,
  1083.   curwin->w_cursor.lnum, curwin->w_cursor.lnum, &len);
  1084.     else
  1085. ret = get_var_var(s, len, retvar);
  1086. }
  1087. else
  1088.     ret = FAIL;
  1089. break;
  1090.     }
  1091.     *arg = skipwhite(*arg);
  1092.     /*
  1093.      * Handle expr[expr] subscript.
  1094.      */
  1095.     if (**arg == '[' && ret == OK)
  1096.     {
  1097. /*
  1098.  * Get the variable from inside the [].
  1099.  */
  1100. *arg = skipwhite(*arg + 1);
  1101. if (eval1(arg, &var2) == FAIL) /* recursive! */
  1102. {
  1103.     clear_var(retvar);
  1104.     return FAIL;
  1105. }
  1106. n = get_var_number(&var2);
  1107. clear_var(&var2);
  1108. /* Check for the ']'. */
  1109. if (**arg != ']')
  1110. {
  1111.     EMSG("Missing ']'");
  1112.     clear_var(retvar);
  1113.     return FAIL;
  1114. }
  1115. /*
  1116.  * The resulting variable is a string of a single character.
  1117.  * If the index is too big or negative, the result is empty.
  1118.  */
  1119. s = get_var_string(retvar);
  1120. if (n >= (long)STRLEN(s) || n < 0)
  1121.     s = NULL;
  1122. else
  1123.     s = vim_strnsave(s + n, 1);
  1124. clear_var(retvar);
  1125. retvar->var_type = VAR_STRING;
  1126. retvar->var_val.var_string = s;
  1127. *arg = skipwhite(*arg + 1); /* skip the ']' */
  1128.     }
  1129.     /*
  1130.      * Apply logical NOT and unary '-', from right to left.
  1131.      */
  1132.     if (ret == OK && end_leader > start_leader)
  1133.     {
  1134. val = get_var_number(retvar);
  1135. while (end_leader > start_leader)
  1136. {
  1137.     --end_leader;
  1138.     if (*end_leader == '!')
  1139. val = !val;
  1140.     else if (*end_leader == '-')
  1141. val = -val;
  1142. }
  1143. clear_var(retvar);
  1144. retvar->var_type = VAR_NUMBER;
  1145. retvar->var_val.var_number = val;
  1146.     }
  1147.     return ret;
  1148. }
  1149. /*
  1150.  * Get an option value.
  1151.  * "arg" points to the '&' before the option name.
  1152.  * "arg" is advanced to character after the option name.
  1153.  * Return OK or FAIL.
  1154.  */
  1155.     static int
  1156. get_option_var(arg, retvar)
  1157.     char_u **arg;
  1158.     VAR retvar; /* when NULL, only check if option exists */
  1159. {
  1160.     char_u *option_end;
  1161.     long numval;
  1162.     char_u *stringval;
  1163.     int opt_type;
  1164.     int c;
  1165.     int ret = OK;
  1166.     /*
  1167.      * Isolate the option name and find its value.
  1168.      */
  1169.     option_end = find_option_end(*arg + 1);
  1170.     if (option_end == *arg + 1)
  1171.     {
  1172. if (retvar != NULL)
  1173.     EMSG2("Option name missing: %s", *arg);
  1174. return FAIL;
  1175.     }
  1176.     c = *option_end;
  1177.     *option_end = NUL;
  1178.     opt_type = get_option_value(*arg + 1, &numval,
  1179.   retvar == NULL ? NULL : &stringval);
  1180.     if (opt_type < 0)     /* invalid name */
  1181.     {
  1182. if (retvar != NULL)
  1183.     EMSG2("Unknown option: %s", *arg + 1);
  1184. ret = FAIL;
  1185.     }
  1186.     else if (retvar != NULL)
  1187.     {
  1188. if (opt_type == 1) /* number option */
  1189. {
  1190.     retvar->var_type = VAR_NUMBER;
  1191.     retvar->var_val.var_number = numval;
  1192. }
  1193. else /* string option */
  1194. {
  1195.     retvar->var_type = VAR_STRING;
  1196.     retvar->var_val.var_string = stringval;
  1197. }
  1198.     }
  1199.     *option_end = c;     /* put back for error messages */
  1200.     *arg = option_end;
  1201.     return ret;
  1202. }
  1203. /*
  1204.  * Allocate a variable for an string constant.
  1205.  * Return OK or FAIL.
  1206.  */
  1207.     static int
  1208. get_string_var(arg, retvar)
  1209.     char_u **arg;
  1210.     VAR retvar;
  1211. {
  1212.     char_u *p;
  1213.     char_u *name;
  1214.     int i;
  1215.     int extra = 0;
  1216.     /*
  1217.      * Find the end of the string, skipping backslashed characters.
  1218.      */
  1219.     for (p = *arg + 1; *p && *p != '"'; ++p)
  1220. if (*p == '\' && p[1] != NUL)
  1221. {
  1222.     ++p;
  1223.     /* A "<x>" form occupies at least 4 characters, and produces up
  1224.      * to 6 characters: reserve space for 2 extra */
  1225.     if (*p == '<')
  1226. extra += 2;
  1227. }
  1228.     if (*p != '"')
  1229.     {
  1230. EMSG2("Missing quote: %s", *arg);
  1231. return FAIL;
  1232.     }
  1233.     /*
  1234.      * Copy the string into allocated memory, handling backslashed
  1235.      * characters.
  1236.      */
  1237.     name = alloc((unsigned)(p - *arg + extra));
  1238.     if (name == NULL)
  1239. return FAIL;
  1240.     i = 0;
  1241.     for (p = *arg + 1; *p && *p != '"'; ++p)
  1242.     {
  1243. if (*p == '\')
  1244. {
  1245.     switch (*++p)
  1246.     {
  1247. case 'b': name[i++] = BS; break;
  1248. case 'e': name[i++] = ESC; break;
  1249. case 'f': name[i++] = FF; break;
  1250. case 'n': name[i++] = NL; break;
  1251. case 'r': name[i++] = CR; break;
  1252. case 't': name[i++] = TAB; break;
  1253.   /* hex: "x1", "x12" */
  1254. case 'X':
  1255. case 'x': if (isxdigit(p[1]))
  1256.   {
  1257.       ++p;
  1258.       name[i] = hex2nr(*p);
  1259.       if (isxdigit(p[1]))
  1260.       {
  1261.   ++p;
  1262.   name[i] = (name[i] << 4) + hex2nr(*p);
  1263.       }
  1264.       ++i;
  1265.   }
  1266.   else
  1267.       name[i++] = *p;
  1268.   break;
  1269.   /* octal: "1", "12", "123" */
  1270. case '0':
  1271. case '1':
  1272. case '2':
  1273. case '3':
  1274. case '4':
  1275. case '5':
  1276. case '6':
  1277. case '7': name[i] = *p - '0';
  1278.   if (p[1] >= '0' && p[1] <= '7')
  1279.   {
  1280.       ++p;
  1281.       name[i] = (name[i] << 3) + *p - '0';
  1282.       if (p[1] >= '0' && p[1] <= '7')
  1283.       {
  1284.   ++p;
  1285.   name[i] = (name[i] << 3) + *p - '0';
  1286.       }
  1287.   }
  1288.   ++i;
  1289.   break;
  1290.     /* Special key, e.g.: "<C-W>" */
  1291. case '<': extra = trans_special(&p, name + i, FALSE);
  1292.   if (extra)
  1293.   {
  1294.       i += extra;
  1295.       --p;
  1296.       break;
  1297.   }
  1298.   /* FALLTHROUGH */
  1299. default:  name[i++] = *p;
  1300.   break;
  1301.     }
  1302. }
  1303. else
  1304.     name[i++] = *p;
  1305.     }
  1306.     name[i] = NUL;
  1307.     *arg = p + 1;
  1308.     retvar->var_type = VAR_STRING;
  1309.     retvar->var_val.var_string = name;
  1310.     return OK;
  1311. }
  1312. /*
  1313.  * Allocate a variable for an backtick-string constant.
  1314.  * Return OK or FAIL.
  1315.  */
  1316.     static int
  1317. get_lit_string_var(arg, retvar)
  1318.     char_u **arg;
  1319.     VAR retvar;
  1320. {
  1321.     char_u *p;
  1322.     char_u *name;
  1323.     /*
  1324.      * Find the end of the string.
  1325.      */
  1326.     p = vim_strchr(*arg + 1, ''');
  1327.     if (p == NULL)
  1328.     {
  1329. EMSG2("Missing quote: %s", *arg);
  1330. return FAIL;
  1331.     }
  1332.     /*
  1333.      * Copy the string into allocated memory.
  1334.      */
  1335.     name = vim_strnsave(*arg + 1, (int)(p - (*arg + 1)));
  1336.     if (name == NULL)
  1337. return FAIL;
  1338.     *arg = p + 1;
  1339.     retvar->var_type = VAR_STRING;
  1340.     retvar->var_val.var_string = name;
  1341.     return OK;
  1342. }
  1343. /*
  1344.  * Get the value of an environment variable.
  1345.  * Return OK or FAIL.
  1346.  */
  1347.     static int
  1348. get_env_var(arg, retvar)
  1349.     char_u **arg;
  1350.     VAR retvar;
  1351. {
  1352.     char_u *string;
  1353.     string = get_env_string(arg);
  1354.     /*
  1355.      * Allocate a variable.  If the environment variable was not set, silently
  1356.      * assume it is empty.
  1357.      */
  1358.     if (string != NULL)
  1359. string = vim_strsave(string);
  1360.     retvar->var_type = VAR_STRING;
  1361.     retvar->var_val.var_string = string;
  1362.     return OK;
  1363. }
  1364. /*
  1365.  * Allocate a variable for the result of a function.
  1366.  * Return OK or FAIL.
  1367.  */
  1368.     static int
  1369. get_func_var(name, len, retvar, arg, firstline, lastline, doesrange)
  1370.     char_u *name; /* name of the function */
  1371.     int len; /* length of "name" */
  1372.     VAR retvar;
  1373.     char_u **arg; /* argument, pointing to the '(' */
  1374.     linenr_t firstline; /* first line of range */
  1375.     linenr_t lastline; /* last line of range */
  1376.     int *doesrange; /* return: function handled range */
  1377. {
  1378.     char_u *argp;
  1379.     int ret = FAIL;
  1380. #define MAX_FUNC_ARGS 20
  1381.     var argvars[MAX_FUNC_ARGS]; /* vars for arguments */
  1382.     int argcount = 0; /* number of arguments found */
  1383.     static char *errors[] =
  1384. {"Invalid arguments for function %s",
  1385.  "Unknown function: %s",
  1386.  "Too many arguments for function: %s",
  1387.  "Not enough arguments for function: %s",
  1388. };
  1389. #define ERROR_INVARG 0
  1390. #define ERROR_UNKOWN 1
  1391. #define ERROR_TOOMANY 2
  1392. #define ERROR_TOOFEW 3
  1393. #define ERROR_NONE 4
  1394. #define ERROR_OTHER 5
  1395.     int error = ERROR_NONE;
  1396.     int i;
  1397.     struct ufunc *fp;
  1398.     int cc;
  1399.     static struct fst
  1400.     {
  1401. char *f_name; /* function name */
  1402. char f_min_argc; /* minimal number of arguments */
  1403. char f_max_argc; /* miximal number of arguments */
  1404. void (*f_func) __ARGS((VAR args, VAR rvar));    /* impl. function */
  1405.     } functions[] =
  1406.     {
  1407. {"argc", 0, 0, f_argc},
  1408. {"argv", 1, 1, f_argv},
  1409. {"browse", 4, 4, f_browse},
  1410. {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */
  1411. {"bufexists", 1, 1, f_bufexists},
  1412. {"buffer_name", 1, 1, f_bufname}, /* obsolete */
  1413. {"buffer_number", 1, 1, f_bufnr}, /* obsolete */
  1414. {"bufname", 1, 1, f_bufname},
  1415. {"bufnr", 1, 1, f_bufnr},
  1416. {"char2nr", 1, 1, f_char2nr},
  1417. {"col", 1, 1, f_col},
  1418. {"confirm", 2, 4, f_confirm},
  1419. {"delete", 1, 1, f_delete},
  1420. {"escape", 2, 2, f_escape},
  1421. {"exists", 1, 1, f_exists},
  1422. {"expand", 1, 1, f_expand},
  1423. {"file_readable", 1, 1, f_filereadable}, /* obsolete */
  1424. {"filereadable", 1, 1, f_filereadable},
  1425. {"fnamemodify", 2, 2, f_fnamemodify},
  1426. {"getcwd", 0, 0, f_getcwd},
  1427. {"getline", 1, 1, f_getline},
  1428. {"has", 1, 1, f_has},
  1429. {"highlight_exists", 1, 1, f_hlexists}, /* obsolete */
  1430. {"highlightID", 1, 1, f_hlID}, /* obsolete */
  1431. {"hlexists", 1, 1, f_hlexists},
  1432. {"hlID", 1, 1, f_hlID},
  1433. {"hostname", 0, 0, f_hostname},
  1434. {"input", 1, 1, f_input },
  1435. {"isdirectory", 1, 1, f_isdirectory},
  1436. {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */
  1437. {"line", 1, 1, f_line},
  1438. {"match", 2, 2, f_match},
  1439. {"matchend", 2, 2, f_matchend},
  1440. {"matchstr", 2, 2, f_matchstr},
  1441. {"nr2char", 1, 1, f_nr2char},
  1442. {"setline", 2, 2, f_setline},
  1443. #ifdef HAVE_STRFTIME
  1444. {"strftime", 1, 1, f_strftime},
  1445. #endif
  1446. {"strlen", 1, 1, f_strlen},
  1447. {"strpart", 3, 3, f_strpart},
  1448. {"synID", 3, 3, f_synID},
  1449. {"synIDattr", 2, 3, f_synIDattr},
  1450. {"synIDtrans", 1, 1, f_synIDtrans},
  1451. {"substitute", 4, 4, f_substitute},
  1452. {"tempname", 0, 0, f_tempname},
  1453. {"virtcol", 1, 1, f_virtcol},
  1454. {"winbufnr", 1, 1, f_winbufnr},
  1455. {"winheight", 1, 1, f_winheight},
  1456. {"winnr", 0, 0, f_winnr},
  1457.     };
  1458.     cc = name[len];
  1459.     name[len] = NUL;
  1460.     *doesrange = FALSE;
  1461.     /*
  1462.      * Get the arguments.
  1463.      */
  1464.     argp = *arg;
  1465.     while (argcount < MAX_FUNC_ARGS)
  1466.     {
  1467. argp = skipwhite(argp + 1);     /* skip the '(' or ',' */
  1468. if (*argp == ')' || *argp == ',' || *argp == NUL)
  1469.     break;
  1470. if (eval1(&argp, &argvars[argcount]) == FAIL)
  1471. {
  1472.     error = ERROR_OTHER;
  1473.     break;
  1474. }
  1475. ++argcount;
  1476. if (*argp != ',')
  1477.     break;
  1478.     }
  1479.     if (*argp != ')' && error == ERROR_NONE)
  1480. error = ERROR_INVARG;
  1481.     /* execute the function if no errors detected and executing */
  1482.     if (error == ERROR_NONE && !emsg_off)
  1483.     {
  1484. retvar->var_type = VAR_NUMBER; /* default is number retvar */
  1485. error = ERROR_UNKOWN;
  1486. if (!islower(name[0]))
  1487. {
  1488.     /*
  1489.      * User defined function.
  1490.      */
  1491.     fp = find_func(name);
  1492.     if (fp != NULL)
  1493.     {
  1494. if (fp->flags & FC_RANGE)
  1495.     *doesrange = TRUE;
  1496. if (argcount < fp->args.ga_len)
  1497.     error = ERROR_TOOFEW;
  1498. else if (!fp->varargs && argcount > fp->args.ga_len)
  1499.     error = ERROR_TOOMANY;
  1500. else
  1501. {
  1502.     /*
  1503.      * Call the user function.
  1504.      * Save and restore search patterns and redo buffer.
  1505.      */
  1506.     save_search_patterns();
  1507.     saveRedobuff();
  1508.     call_func(fp, argcount, argvars, retvar,
  1509.  firstline, lastline);
  1510.     restoreRedobuff();
  1511.     restore_search_patterns();
  1512.     error = ERROR_NONE;
  1513. }
  1514.     }
  1515. }
  1516. else
  1517. {
  1518.     /*
  1519.      * Find the function name in the table, call its implementation.
  1520.      */
  1521.     for (i = 0; i < (int)(sizeof(functions) / sizeof(struct fst)); ++i)
  1522. if (STRCMP(name, functions[i].f_name) == 0)
  1523. {
  1524.     if (argcount < functions[i].f_min_argc)
  1525. error = ERROR_TOOFEW;
  1526.     else if (argcount > functions[i].f_max_argc)
  1527. error = ERROR_TOOMANY;
  1528.     else
  1529.     {
  1530. argvars[argcount].var_type = VAR_UNKNOWN;
  1531. functions[i].f_func(argvars, retvar);
  1532. error = ERROR_NONE;
  1533.     }
  1534.     break;
  1535. }
  1536. }
  1537. *arg = skipwhite(argp + 1);
  1538. if (error == ERROR_NONE)
  1539.     ret = OK;
  1540.     }
  1541.     while (--argcount >= 0)
  1542. clear_var(&argvars[argcount]);
  1543.     if (error < ERROR_NONE)
  1544. EMSG2((char_u *)errors[error], name);
  1545.     name[len] = cc;
  1546.     return ret;
  1547. }
  1548. /*
  1549.  * "argc()" function.
  1550.  */
  1551. /* ARGSUSED */
  1552.     static void
  1553. f_argc(argvars, retvar)
  1554.     VAR argvars;
  1555.     VAR retvar;
  1556. {
  1557.     retvar->var_val.var_number = arg_file_count;
  1558. }
  1559. /*
  1560.  * "argv()" function.
  1561.  */
  1562.     static void
  1563. f_argv(argvars, retvar)
  1564.     VAR argvars;
  1565.     VAR retvar;
  1566. {
  1567.     int idx;
  1568.     idx = get_var_number(&argvars[0]);
  1569.     if (idx >= 0 && idx < arg_file_count)
  1570. retvar->var_val.var_string = vim_strsave(arg_files[idx]);
  1571.     else
  1572. retvar->var_val.var_string = NULL;
  1573.     retvar->var_type = VAR_STRING;
  1574. }
  1575.     static BUF *
  1576. get_buf_var(avar)
  1577.     VAR avar;
  1578. {
  1579.     char_u *name = avar->var_val.var_string;
  1580.     if (avar->var_type == VAR_NUMBER)
  1581. return buflist_findnr((int)avar->var_val.var_number);
  1582.     else if (name == NULL || *name == NUL)
  1583. return curbuf;
  1584.     else if (name[0] == '$' && name[1] == NUL)
  1585. return lastbuf;
  1586.     else
  1587. return buflist_findnr(buflist_findpat(name, name + STRLEN(name)));
  1588. }
  1589. /*
  1590.  * "buffer_name()" function.
  1591.  */
  1592.     static void
  1593. f_bufname(argvars, retvar)
  1594.     VAR argvars;
  1595.     VAR retvar;
  1596. {
  1597.     BUF *buf;
  1598.     ++emsg_off;
  1599.     buf = get_buf_var(&argvars[0]);
  1600.     retvar->var_type = VAR_STRING;
  1601.     if (buf != NULL && buf->b_fname != NULL)
  1602. retvar->var_val.var_string = vim_strsave(buf->b_fname);
  1603.     else
  1604. retvar->var_val.var_string = NULL;
  1605.     --emsg_off;
  1606. }
  1607. /*
  1608.  * "buffer_number()" function.
  1609.  */
  1610.     static void
  1611. f_bufnr(argvars, retvar)
  1612.     VAR argvars;
  1613.     VAR retvar;
  1614. {
  1615.     BUF *buf;
  1616.     ++emsg_off;
  1617.     buf = get_buf_var(&argvars[0]);
  1618.     if (buf != NULL)
  1619. retvar->var_val.var_number = buf->b_fnum;
  1620.     else
  1621. retvar->var_val.var_number = -1;
  1622.     --emsg_off;
  1623. }
  1624. /*
  1625.  * "buffer_exists()" function.
  1626.  */
  1627.     static void
  1628. f_bufexists(argvars, retvar)
  1629.     VAR argvars;
  1630.     VAR retvar;
  1631. {
  1632.     int n = FALSE;
  1633.     char_u *name;
  1634.     if (argvars[0].var_type == VAR_NUMBER)
  1635. n = (buflist_findnr((int)argvars[0].var_val.var_number) != NULL);
  1636.     else if (argvars[0].var_val.var_string != NULL)
  1637.     {
  1638. /* First make the name into a full path name */
  1639. name = FullName_save(argvars[0].var_val.var_string,
  1640. #ifdef UNIX
  1641. TRUE     /* force expansion, get rid of symbolic links */
  1642. #else
  1643. FALSE
  1644. #endif
  1645. );
  1646. if (name != NULL)
  1647. {
  1648.     n = (buflist_findname(name) != NULL);
  1649.     vim_free(name);
  1650. }
  1651.     }
  1652.     retvar->var_val.var_number = n;
  1653. }
  1654. /*
  1655.  * "char2nr()" function
  1656.  */
  1657.     static void
  1658. f_char2nr(argvars, retvar)
  1659.     VAR argvars;
  1660.     VAR retvar;
  1661. {
  1662.     retvar->var_val.var_number = get_var_string(&argvars[0])[0];
  1663. }
  1664. /*
  1665.  * "col(string)" function
  1666.  */
  1667.     static void
  1668. f_col(argvars, retvar)
  1669.     VAR argvars;
  1670.     VAR retvar;
  1671. {
  1672.     colnr_t col = 0;
  1673.     FPOS *fp;
  1674.     fp = var2fpos(&argvars[0]);
  1675.     if (fp != NULL && fp->lnum > 0)
  1676. col = fp->col + 1;
  1677.     retvar->var_val.var_number = col;
  1678. }
  1679. /*
  1680.  * "confirm(message, buttons[, default [, type]])" function
  1681.  */
  1682.     static void
  1683. f_confirm(argvars, retvar)
  1684.     VAR argvars;
  1685.     VAR retvar;
  1686. {
  1687. #if defined(GUI_DIALOG) || defined(CON_DIALOG)
  1688.     char_u *message;
  1689.     char_u *buttons;
  1690.     char_u buf[NUMBUFLEN];
  1691.     char_u buf2[NUMBUFLEN];
  1692.     int def = 0;
  1693.     int type = VIM_GENERIC;
  1694.     int c;
  1695.     message = get_var_string(&argvars[0]);
  1696.     buttons = get_var_string_buf(&argvars[1], buf);
  1697.     if (argvars[2].var_type != VAR_UNKNOWN)
  1698.     {
  1699. def = get_var_number(&argvars[2]);
  1700. if (argvars[3].var_type != VAR_UNKNOWN)
  1701. {
  1702.     /* avoid that TO_UPPER calls get_var_string_buf() twice */
  1703.     c = *get_var_string_buf(&argvars[3], buf2);
  1704.     switch (TO_UPPER(c))
  1705.     {
  1706. case 'E': type = VIM_ERROR; break;
  1707. case 'Q': type = VIM_QUESTION; break;
  1708. case 'I': type = VIM_INFO; break;
  1709. case 'W': type = VIM_WARNING; break;
  1710. case 'G': type = VIM_GENERIC; break;
  1711.     }
  1712. }
  1713.     }
  1714.     retvar->var_val.var_number = do_dialog(type, NULL, message, buttons, def);
  1715. #else
  1716.     retvar->var_val.var_number = 0;
  1717. #endif
  1718. }
  1719. /*
  1720.  * "browse(save, title, initdir, default)" function
  1721.  */
  1722. /* ARGSUSED */
  1723.     static void
  1724. f_browse(argvars, retvar)
  1725.     VAR argvars;
  1726.     VAR retvar;
  1727. {
  1728. #ifdef USE_BROWSE
  1729.     int save;
  1730.     char_u *title;
  1731.     char_u *initdir;
  1732.     char_u *defname;
  1733.     char_u buf[NUMBUFLEN];
  1734.     char_u buf2[NUMBUFLEN];
  1735.     save = get_var_number(&argvars[0]);
  1736.     title = get_var_string(&argvars[1]);
  1737.     initdir = get_var_string_buf(&argvars[2], buf);
  1738.     defname = get_var_string_buf(&argvars[3], buf2);
  1739.     retvar->var_val.var_string =
  1740.  do_browse(save, title, defname, NULL, initdir, NULL, curbuf);
  1741. #else
  1742.     retvar->var_val.var_string = NULL;
  1743. #endif
  1744.     retvar->var_type = VAR_STRING;
  1745. }
  1746. /*
  1747.  * "delete()" function
  1748.  */
  1749.     static void
  1750. f_delete(argvars, retvar)
  1751.     VAR argvars;
  1752.     VAR retvar;
  1753. {
  1754.     retvar->var_val.var_number = mch_remove(get_var_string(&argvars[0]));
  1755. }
  1756. /*
  1757.  * "escape({string}, {chars})" function
  1758.  */
  1759.     static void
  1760. f_escape(argvars, retvar)
  1761.     VAR argvars;
  1762.     VAR retvar;
  1763. {
  1764.     char_u buf[NUMBUFLEN];
  1765.     retvar->var_val.var_string =
  1766. vim_strsave_escaped(get_var_string(&argvars[0]),
  1767. get_var_string_buf(&argvars[1], buf));
  1768.     retvar->var_type = VAR_STRING;
  1769. }
  1770. /*
  1771.  * "exists()" function
  1772.  */
  1773.     static void
  1774. f_exists(argvars, retvar)
  1775.     VAR argvars;
  1776.     VAR retvar;
  1777. {
  1778.     char_u *p;
  1779.     char_u *name;
  1780.     int n = FALSE;
  1781.     int len;
  1782.     p = get_var_string(&argvars[0]);
  1783.     if (*p == '$') /* environment variable */
  1784. n = (get_env_string(&p) != NULL);
  1785.     else if (*p == '&') /* option */
  1786. n = (get_option_var(&p, NULL) == OK);
  1787.     else /* internal variable */
  1788.     {
  1789. name = p;
  1790. len = get_id_len(&p);
  1791. if (len != 0)
  1792.     n = (get_var_var(name, len, NULL) == OK);
  1793.     }
  1794.     retvar->var_val.var_number = n;
  1795. }
  1796. /*
  1797.  * "expand()" function
  1798.  */
  1799.     static void
  1800. f_expand(argvars, retvar)
  1801.     VAR argvars;
  1802.     VAR retvar;
  1803. {
  1804.     char_u *s;
  1805.     int len;
  1806.     char_u *errormsg;
  1807.     retvar->var_type = VAR_STRING;
  1808.     s = get_var_string(&argvars[0]);
  1809.     if (*s == '%' || *s == '#' || *s == '<')
  1810. retvar->var_val.var_string = eval_vars(s, &len, NULL, &errormsg, s);
  1811.     else
  1812. retvar->var_val.var_string = ExpandOne(s, NULL, WILD_USE_NL, WILD_ALL);
  1813. }
  1814. /*
  1815.  * "filereadable()" function
  1816.  */
  1817.     static void
  1818. f_filereadable(argvars, retvar)
  1819.     VAR argvars;
  1820.     VAR retvar;
  1821. {
  1822.     FILE *fd;
  1823.     char_u *p;
  1824.     int n;
  1825.     p = get_var_string(&argvars[0]);
  1826.     if (*p && !mch_isdir(p) && (fd = fopen((char *)p, "r")) != NULL)
  1827.     {
  1828. n = TRUE;
  1829. fclose(fd);
  1830.     }
  1831.     else
  1832. n = FALSE;
  1833.     retvar->var_val.var_number = n;
  1834. }
  1835. /*
  1836.  * "fnamemodify({fname}, {mods})" function
  1837.  */
  1838.     static void
  1839. f_fnamemodify(argvars, retvar)
  1840.     VAR argvars;
  1841.     VAR retvar;
  1842. {
  1843.     char_u *fname;
  1844.     char_u *mods;
  1845.     int usedlen = 0;
  1846.     int len;
  1847.     char_u *fbuf = NULL;
  1848.     char_u buf[NUMBUFLEN];
  1849.     fname = get_var_string(&argvars[0]);
  1850.     mods = get_var_string_buf(&argvars[1], buf);
  1851.     len = STRLEN(fname);
  1852.     (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
  1853.     retvar->var_type = VAR_STRING;
  1854.     if (fname == NULL)
  1855. retvar->var_val.var_string = NULL;
  1856.     else
  1857. retvar->var_val.var_string = vim_strnsave(fname, len);
  1858.     vim_free(fbuf);
  1859. }
  1860. /*
  1861.  * "getcwd()" function
  1862.  */
  1863. /*ARGSUSED*/
  1864.     static void
  1865. f_getcwd(argvars, retvar)
  1866.     VAR argvars;
  1867.     VAR retvar;
  1868. {
  1869.     char_u cwd[MAXPATHL];
  1870.     retvar->var_type = VAR_STRING;
  1871.     if (mch_dirname(cwd, MAXPATHL) == FAIL)
  1872. retvar->var_val.var_string = NULL;
  1873.     else
  1874. retvar->var_val.var_string = vim_strsave(cwd);
  1875. }
  1876. /*
  1877.  * "getline(lnum)" function
  1878.  */
  1879.     static void
  1880. f_getline(argvars, retvar)
  1881.     VAR argvars;
  1882.     VAR retvar;
  1883. {
  1884.     linenr_t lnum;
  1885.     char_u *p;
  1886.     lnum = get_var_number(&argvars[0]);
  1887.     if (lnum == 0)  /* no valid number, try using line() */
  1888.     {
  1889. f_line(argvars, retvar);
  1890. lnum = retvar->var_val.var_number;
  1891. clear_var(retvar);
  1892.     }
  1893.     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
  1894. p = ml_get(lnum);
  1895.     else
  1896. p = (char_u *)"";
  1897.     retvar->var_type = VAR_STRING;
  1898.     retvar->var_val.var_string = vim_strsave(p);
  1899. }
  1900. /*
  1901.  * "has()" function
  1902.  */
  1903.     static void
  1904. f_has(argvars, retvar)
  1905.     VAR argvars;
  1906.     VAR retvar;
  1907. {
  1908.     int i;
  1909.     char_u *name;
  1910.     int n = FALSE;
  1911.     static char *(has_list[]) =
  1912.     {
  1913. #ifdef AMIGA
  1914. "amiga",
  1915. # ifndef NO_ARP
  1916. "arp",
  1917. # endif
  1918. #endif
  1919. #ifdef __BEOS__
  1920. "beos",
  1921. #endif
  1922. #ifdef MSDOS
  1923. # ifdef DJGPP
  1924. "dos32",
  1925. # else
  1926. "dos16",
  1927. # endif
  1928. #endif
  1929. #ifdef macintosh
  1930. "mac",
  1931. #endif
  1932. #ifdef RISCOS
  1933. "riscos",
  1934. #endif
  1935. #ifdef UNIX
  1936. "unix",
  1937. #endif
  1938. #ifdef VMS
  1939. "vms",
  1940. #endif
  1941. #ifdef WIN32
  1942. "win32",
  1943. #endif
  1944. #ifndef CASE_INSENSITIVE_FILENAME
  1945. "fname_case",
  1946. #endif
  1947. #ifdef AUTOCMD
  1948. "autocmd",
  1949. #endif
  1950. #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS)
  1951. "builtin_terms",
  1952. # ifdef ALL_BUILTIN_TCAPS
  1953. "all_builtin_terms",
  1954. # endif
  1955. #endif
  1956. #ifdef CINDENT
  1957. "cindent",
  1958. #endif
  1959. #ifdef USE_CSCOPE
  1960. "cscope",
  1961. #endif
  1962. #ifdef DEBUG
  1963. "debug",
  1964. #endif
  1965. #ifdef CON_DIALOG
  1966. "dialog_con",
  1967. #endif
  1968. #ifdef GUI_DIALOG
  1969. "dialog_gui",
  1970. #endif
  1971. #ifdef DIGRAPHS
  1972. "digraphs",
  1973. #endif
  1974. #ifdef EMACS_TAGS
  1975. "emacs_tags",
  1976. #endif
  1977. "eval",     /* always present, of course! */
  1978. #ifdef EX_EXTRA
  1979. "ex_extra",
  1980. #endif
  1981. #ifdef EXTRA_SEARCH
  1982. "extra_search",
  1983. #endif
  1984. #ifdef FKMAP
  1985. "farsi",
  1986. #endif
  1987. #ifdef FILE_IN_PATH
  1988. "file_in_path",
  1989. #endif
  1990. #ifdef WANT_FILETYPE
  1991. "filetype",
  1992. #endif
  1993. #ifdef FIND_IN_PATH
  1994. "find_in_path",
  1995. #endif
  1996. #if !defined(USE_SYSTEM) && defined(UNIX)
  1997. "fork",
  1998. #endif
  1999. #ifdef USE_GUI
  2000. "gui",
  2001. #endif
  2002. #ifdef USE_GUI_ATHENA
  2003. "gui_athena",
  2004. #endif
  2005. #ifdef USE_GUI_BEOS
  2006. "gui_beos",
  2007. #endif
  2008. #ifdef USE_GUI_MAC
  2009. "gui_mac",
  2010. #endif
  2011. #ifdef USE_GUI_MOTIF
  2012. "gui_motif",
  2013. #endif
  2014. #ifdef USE_GUI_WIN32
  2015. "gui_win32",
  2016. #endif
  2017. #ifdef INSERT_EXPAND
  2018. "insert_expand",
  2019. #endif
  2020. #ifdef HAVE_LANGMAP
  2021. "langmap",
  2022. #endif
  2023. #ifdef LISPINDENT
  2024. "lispindent",
  2025. #endif
  2026. #ifdef WANT_MODIFY_FNAME
  2027. "modify_fname",
  2028. #endif
  2029. #ifdef USE_MOUSE
  2030. "mouse",
  2031. #endif
  2032. #ifdef UNIX
  2033. # ifdef DEC_MOUSE
  2034. "mouse_dec",
  2035. # endif
  2036. # ifdef NETTERM_MOUSE
  2037. "mouse_netterm",
  2038. # endif
  2039. # ifdef XTERM_MOUSE
  2040. "mouse_xterm",
  2041. # endif
  2042. #endif
  2043. #ifdef MULTI_BYTE
  2044. "multi_byte",
  2045. #endif
  2046. #ifdef MULTI_BYTE_IME
  2047. "multi_byte_ime",
  2048. #endif
  2049. #ifdef HAVE_OLE
  2050. "ole",
  2051. #endif
  2052. #ifdef HAVE_PERL_INTERP
  2053. "perl",
  2054. #endif
  2055. #ifdef HAVE_PYTHON
  2056. "python",
  2057. #endif
  2058. #ifdef QUICKFIX
  2059. "quickfix",
  2060. #endif
  2061. #ifdef RIGHTLEFT
  2062. "rightleft",
  2063. #endif
  2064. #ifdef SHOWCMD
  2065. "showcmd",
  2066. #endif
  2067. #ifdef SMARTINDENT
  2068. "smartindent",
  2069. #endif
  2070. #ifdef SYNTAX_HL
  2071. "syntax",
  2072. #endif
  2073. #if defined(USE_SYSTEM) || !defined(UNIX)
  2074. "system",
  2075. #endif
  2076. #ifdef BINARY_TAGS
  2077. "tag_binary",
  2078. #endif
  2079. #ifdef OLD_STATIC_TAGS
  2080. "tag_old_static",
  2081. #endif
  2082. #ifdef TAG_ANY_WHITE
  2083. "tag_any_white",
  2084. #endif
  2085. #ifdef HAVE_TCL
  2086. "tcl",
  2087. #endif
  2088. #ifdef TERMINFO
  2089. "terminfo",
  2090. #endif
  2091. #ifdef TEXT_OBJECTS
  2092. "textobjects",
  2093. #endif
  2094. #ifdef HAVE_TGETENT
  2095. "tgetent",
  2096. #endif
  2097. #ifdef USER_COMMANDS
  2098. "user-commands",
  2099. #endif
  2100. #ifdef VIMINFO
  2101. "viminfo",
  2102. #endif
  2103. #ifdef WILDIGNORE
  2104. "wildignore",
  2105. #endif
  2106. #ifdef WRITEBACKUP
  2107. "writebackup",
  2108. #endif
  2109. #ifdef SAVE_XTERM_SCREEN
  2110. "xterm_save",
  2111. #endif
  2112. #if defined(UNIX) && defined(WANT_X11) && defined(HAVE_X11)
  2113. "X11",
  2114. #endif
  2115. NULL
  2116.     };
  2117.     name = get_var_string(&argvars[0]);
  2118.     for (i = 0; has_list[i] != NULL; ++i)
  2119. if (STRICMP(name, has_list[i]) == 0)
  2120. {
  2121.     n = TRUE;
  2122.     break;
  2123. }
  2124.     if (n == FALSE)
  2125.     {
  2126. #ifdef USE_GUI
  2127. if (STRICMP(name, "gui_running") == 0)
  2128. {
  2129.     n = (gui.in_use || gui.starting);
  2130. }
  2131. # ifdef USE_GUI_WIN32
  2132. else if (STRICMP(name, "gui_win32s") == 0)
  2133. {
  2134.     n = gui_is_win32s();
  2135. }
  2136. # endif
  2137. #ifdef USE_BROWSE
  2138. else if (STRICMP(name, "browse") == 0)
  2139. {
  2140.     n = gui.in_use; /* gui_mch_browse() works when GUI is running */
  2141. }
  2142. #endif
  2143. #endif
  2144. #ifdef SYNTAX_HL
  2145. # ifdef USE_GUI
  2146. else
  2147. # endif
  2148.     if (STRICMP(name, "syntax_items") == 0)
  2149. {
  2150.     n = syntax_present(curbuf);
  2151. }
  2152. #endif
  2153.     }
  2154.     retvar->var_val.var_number = n;
  2155. }
  2156. /*
  2157.  * "highlight_exists()" function
  2158.  */
  2159.     static void
  2160. f_hlexists(argvars, retvar)
  2161.     VAR argvars;
  2162.     VAR retvar;
  2163. {
  2164.     retvar->var_val.var_number = highlight_exists(get_var_string(&argvars[0]));
  2165. }
  2166. /*
  2167.  * "highlightID(name)" function
  2168.  */
  2169.     static void
  2170. f_hlID(argvars, retvar)
  2171.     VAR argvars;
  2172.     VAR retvar;
  2173. {
  2174.     retvar->var_val.var_number = syn_name2id(get_var_string(&argvars[0]));
  2175. }
  2176. /*
  2177.  * "hostname()" function
  2178.  */
  2179. /*ARGSUSED*/
  2180.     static void
  2181. f_hostname(argvars, retvar)
  2182.     VAR argvars;
  2183.     VAR retvar;
  2184. {
  2185.     char_u hostname[256];
  2186.     mch_get_host_name(hostname, 256);
  2187.     retvar->var_type = VAR_STRING;
  2188.     retvar->var_val.var_string = vim_strsave(hostname);
  2189. }
  2190. /*
  2191.  * "input()" function
  2192.  */
  2193.     static void
  2194. f_input(argvars, retvar)
  2195.     VAR argvars;
  2196.     VAR retvar;
  2197. {
  2198.     char_u *prompt = get_var_string(&argvars[0]);
  2199.     char_u *p;
  2200.     int c;
  2201.     retvar->var_type = VAR_STRING;
  2202. #ifdef NO_CONSOLE
  2203.     /*
  2204.      * While starting up, there is no place to enter text.
  2205.      */
  2206.     if (!gui.in_use || gui.starting)
  2207.     {
  2208. retvar->var_val.var_string = NULL;
  2209. return;
  2210.     }
  2211. #endif
  2212.     if (prompt != NULL)
  2213.     {
  2214. /* Only the part of the message after the last NL is considered as
  2215.  * prompt for the command line */
  2216. p = vim_strrchr(prompt, 'n');
  2217. if (p == NULL)
  2218.     p = prompt;
  2219. else
  2220. {
  2221.     ++p;
  2222.     c = *p;
  2223.     *p = NUL;
  2224.     msg_start();
  2225.     msg_clr_eos();
  2226.     msg_puts_attr(prompt, echo_attr);
  2227.     msg_didout = FALSE;
  2228.     *p = c;
  2229. }
  2230. cmdline_prompt(p, echo_attr);
  2231. cmdline_row = msg_row;
  2232.     }
  2233.     retvar->var_val.var_string = getexline('@', NULL, 0);
  2234.     cmdline_prompt(NULL, 0);
  2235.     /* since the user typed this, no need to wait for return */
  2236.     need_wait_return = FALSE;
  2237.     msg_didout = FALSE;
  2238.     dont_wait_return = TRUE;
  2239. }
  2240. /*
  2241.  * "isdirectory()" function
  2242.  */
  2243.     static void
  2244. f_isdirectory(argvars, retvar)
  2245.     VAR argvars;
  2246.     VAR retvar;
  2247. {
  2248.     retvar->var_val.var_number = mch_isdir(get_var_string(&argvars[0]));
  2249. }
  2250. /*
  2251.  * "last_buffer_nr()" function.
  2252.  */
  2253. /*ARGSUSED*/
  2254.     static void
  2255. f_last_buffer_nr(argvars, retvar)
  2256.     VAR argvars;
  2257.     VAR retvar;
  2258. {
  2259.     int n = 0;
  2260.     BUF *buf;
  2261.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  2262. if (n < buf->b_fnum)
  2263.     n = buf->b_fnum;
  2264.     retvar->var_val.var_number = n;
  2265. }
  2266. /*
  2267.  * "line(string)" function
  2268.  */
  2269.     static void
  2270. f_line(argvars, retvar)
  2271.     VAR argvars;
  2272.     VAR retvar;
  2273. {
  2274.     linenr_t lnum = 0;
  2275.     FPOS *fp;
  2276.     fp = var2fpos(&argvars[0]);
  2277.     if (fp != NULL)
  2278. lnum = fp->lnum;
  2279.     else if (get_var_string(&argvars[0])[0] == '$')   /* last line in buffer */
  2280. lnum = curbuf->b_ml.ml_line_count;
  2281.     retvar->var_val.var_number = lnum;
  2282. }
  2283. /*
  2284.  * "match()" function
  2285.  */
  2286.     static void
  2287. f_match(argvars, retvar)
  2288.     VAR argvars;
  2289.     VAR retvar;
  2290. {
  2291.     f_some_match(argvars, retvar, 1);
  2292. }
  2293. /*
  2294.  * "matchend()" function
  2295.  */
  2296.     static void
  2297. f_matchend(argvars, retvar)
  2298.     VAR argvars;
  2299.     VAR retvar;
  2300. {
  2301.     f_some_match(argvars, retvar, 0);
  2302. }
  2303. /*
  2304.  * "matchstr()" function
  2305.  */
  2306.     static void
  2307. f_matchstr(argvars, retvar)
  2308.     VAR argvars;
  2309.     VAR retvar;
  2310. {
  2311.     f_some_match(argvars, retvar, 2);
  2312. }
  2313.     static void
  2314. f_some_match(argvars, retvar, type)
  2315.     VAR argvars;
  2316.     VAR retvar;
  2317.     int type;
  2318. {
  2319.     char_u *str;
  2320.     char_u *pat;
  2321.     vim_regexp *prog;
  2322.     char_u patbuf[NUMBUFLEN];
  2323.     str = get_var_string(&argvars[0]);
  2324.     pat = get_var_string_buf(&argvars[1], patbuf);
  2325.     if (type == 2)
  2326.     {
  2327. retvar->var_type = VAR_STRING;
  2328. retvar->var_val.var_string = NULL;
  2329.     }
  2330.     else
  2331. retvar->var_val.var_number = -1;
  2332.     prog = vim_regcomp(pat, TRUE);
  2333.     if (prog != NULL)
  2334.     {
  2335. reg_ic = p_ic;
  2336. if (vim_regexec(prog, str, TRUE))
  2337. {
  2338.     if (type == 2)
  2339. retvar->var_val.var_string = vim_strnsave(prog->startp[0],
  2340.       (int)(prog->endp[0] - prog->startp[0]));
  2341.     else if (type)
  2342. retvar->var_val.var_number = prog->startp[0] - str;
  2343.     else
  2344. retvar->var_val.var_number = prog->endp[0] - str;
  2345. }
  2346. vim_free(prog);
  2347.     }
  2348. }
  2349. /*
  2350.  * "nr2char()" function
  2351.  */
  2352.     static void
  2353. f_nr2char(argvars, retvar)
  2354.     VAR argvars;
  2355.     VAR retvar;
  2356. {
  2357.     char_u buf[2];
  2358.     buf[0] = (char_u)get_var_number(&argvars[0]);
  2359.     retvar->var_type = VAR_STRING;
  2360.     retvar->var_val.var_string = vim_strnsave(buf, 1);
  2361. }
  2362. /*
  2363.  * "setline()" function
  2364.  */
  2365.     static void
  2366. f_setline(argvars, retvar)
  2367.     VAR argvars;
  2368.     VAR retvar;
  2369. {
  2370.     linenr_t lnum;
  2371.     char_u *line;
  2372.     lnum = get_var_number(&argvars[0]);
  2373.     line = get_var_string(&argvars[1]);
  2374.     retvar->var_val.var_number = 1; /* FAIL is default */
  2375.     if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
  2376.     {
  2377. if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK)
  2378. {
  2379.     changed();
  2380. #ifdef SYNTAX_HL
  2381.     /* recompute syntax hl. for this line */
  2382.     syn_changed(lnum);
  2383. #endif
  2384.     redraw_curbuf_later(NOT_VALID);
  2385.     retvar->var_val.var_number = 0;
  2386. }
  2387.     }
  2388. }
  2389. #ifdef HAVE_STRFTIME
  2390. /*
  2391.  * "strftime()" function
  2392.  */
  2393.     static void
  2394. f_strftime(argvars, retvar)
  2395.     VAR argvars;
  2396.     VAR retvar;
  2397. {
  2398.     char_u result_buf[80];
  2399.     struct tm *curtime;
  2400.     time_t seconds;
  2401.     char_u *p;
  2402.     p = get_var_string(&argvars[0]);
  2403.     seconds = time(NULL);
  2404.     curtime = localtime(&seconds);
  2405.     (void)strftime((char *)result_buf, (size_t)80, (char *)p, curtime);
  2406.     retvar->var_type = VAR_STRING;
  2407.     retvar->var_val.var_string = vim_strsave(result_buf);
  2408. }
  2409. #endif
  2410. /*
  2411.  * "strlen()" function
  2412.  */
  2413.     static void
  2414. f_strlen(argvars, retvar)
  2415.     VAR argvars;
  2416.     VAR retvar;
  2417. {
  2418.     retvar->var_val.var_number = STRLEN(get_var_string(&argvars[0]));
  2419. }
  2420. /*
  2421.  * "strpart()" function
  2422.  */
  2423.     static void
  2424. f_strpart(argvars, retvar)
  2425.     VAR argvars;
  2426.     VAR retvar;
  2427. {
  2428.     char_u *p;
  2429.     int n;
  2430.     int len;
  2431.     int slen;
  2432.     p = get_var_string(&argvars[0]);
  2433.     n = get_var_number(&argvars[1]);
  2434.     len = get_var_number(&argvars[2]);
  2435.     slen = STRLEN(p);
  2436.     /*
  2437.      * Only return the overlap between the specified part and the actual
  2438.      * string.
  2439.      */
  2440.     if (n < 0)
  2441.     {
  2442. len += n;
  2443. n = 0;
  2444.     }
  2445.     else if (n > slen)
  2446. n = slen;
  2447.     if (len < 0)
  2448. len = 0;
  2449.     else if (n + len > slen)
  2450. len = slen - n;
  2451.     retvar->var_type = VAR_STRING;
  2452.     retvar->var_val.var_string = vim_strnsave(p + n, len);
  2453. }
  2454. /*
  2455.  * "synID(line, col, trans)" function
  2456.  */
  2457.     static void
  2458. f_synID(argvars, retvar)
  2459.     VAR argvars;
  2460.     VAR retvar;
  2461. {
  2462.     int id = 0;
  2463. #ifdef SYNTAX_HL
  2464.     long line;
  2465.     long col;
  2466.     int trans;
  2467.     line = get_var_number(&argvars[0]);
  2468.     col = get_var_number(&argvars[1]) - 1;
  2469.     trans = get_var_number(&argvars[2]);
  2470.     if (line >= 1 && line <= curbuf->b_ml.ml_line_count
  2471.     && col >= 0 && col < (long)STRLEN(ml_get(line)))
  2472. id = syn_get_id(line, col, trans);
  2473. #endif
  2474.     retvar->var_val.var_number = id;
  2475. }
  2476. /*
  2477.  * "synIDattr(id, what [, mode])" function
  2478.  */
  2479.     static void
  2480. f_synIDattr(argvars, retvar)
  2481.     VAR argvars;
  2482.     VAR retvar;
  2483. {
  2484.     char_u *p = NULL;
  2485. #ifdef SYNTAX_HL
  2486.     int id;
  2487.     char_u *what;
  2488.     char_u *mode;
  2489.     char_u modebuf[NUMBUFLEN];
  2490.     int modec;
  2491.     id = get_var_number(&argvars[0]);
  2492.     what = get_var_string(&argvars[1]);
  2493.     if (argvars[2].var_type != VAR_UNKNOWN)
  2494.     {
  2495. mode = get_var_string_buf(&argvars[2], modebuf);
  2496. modec = TO_LOWER(mode[0]);
  2497. if (modec != 't' && modec != 'c'
  2498. #ifdef USE_GUI
  2499. && modec != 'g'
  2500. #endif
  2501. )
  2502.     modec = 0; /* replace invalid with current */
  2503.     }
  2504.     else
  2505.     {
  2506. #ifdef USE_GUI
  2507. if (gui.in_use)
  2508.     modec = 'g';
  2509. else
  2510. #endif
  2511.     if (*T_CCO)
  2512.     modec = 'c';
  2513. else
  2514.     modec = 't';
  2515.     }
  2516.     switch (TO_LOWER(what[0]))
  2517.     {
  2518. case 'b':
  2519. if (TO_LOWER(what[1]) == 'g') /* bg[#] */
  2520.     p = highlight_color(id, what, modec);
  2521. else /* bold */
  2522.     p = highlight_has_attr(id, HL_BOLD, modec);
  2523. break;
  2524. case 'f': /* fg[#] */
  2525. p = highlight_color(id, what, modec);
  2526. break;
  2527. case 'i':
  2528. if (TO_LOWER(what[1]) == 'n') /* inverse */
  2529.     p = highlight_has_attr(id, HL_INVERSE, modec);
  2530. else /* italic */
  2531.     p = highlight_has_attr(id, HL_ITALIC, modec);
  2532. break;
  2533. case 'n': /* name */
  2534. p = get_highlight_name(id - 1);
  2535. break;
  2536. case 'r': /* reverse */
  2537. p = highlight_has_attr(id, HL_INVERSE, modec);
  2538. break;
  2539. case 's': /* standout */
  2540. p = highlight_has_attr(id, HL_STANDOUT, modec);
  2541. break;
  2542. case 'u': /* underline */
  2543. p = highlight_has_attr(id, HL_UNDERLINE, modec);
  2544. break;
  2545.     }
  2546.     if (p != NULL)
  2547. p = vim_strsave(p);
  2548. #endif
  2549.     retvar->var_type = VAR_STRING;
  2550.     retvar->var_val.var_string = p;
  2551. }
  2552. /*
  2553.  * "synIDtrans(id)" function
  2554.  */
  2555.     static void
  2556. f_synIDtrans(argvars, retvar)
  2557.     VAR argvars;
  2558.     VAR retvar;
  2559. {
  2560.     int id;
  2561. #ifdef SYNTAX_HL
  2562.     id = get_var_number(&argvars[0]);
  2563.     if (id > 0)
  2564. id = syn_get_final_id(id);
  2565.     else
  2566. #endif
  2567. id = 0;
  2568.     retvar->var_val.var_number = id;
  2569. }
  2570. /*
  2571.  * "substitute()" function
  2572.  */
  2573.     static void
  2574. f_substitute(argvars, retvar)
  2575.     VAR argvars;
  2576.     VAR retvar;
  2577. {
  2578.     char_u patbuf[NUMBUFLEN];
  2579.     char_u subbuf[NUMBUFLEN];
  2580.     char_u flagsbuf[NUMBUFLEN];
  2581.     retvar->var_type = VAR_STRING;
  2582.     retvar->var_val.var_string = do_string_sub(
  2583.     get_var_string(&argvars[0]),
  2584.     get_var_string_buf(&argvars[1], patbuf),
  2585.     get_var_string_buf(&argvars[2], subbuf),
  2586.     get_var_string_buf(&argvars[3], flagsbuf));
  2587. }
  2588. /*
  2589.  * "tempname()" function
  2590.  */
  2591. /*ARGSUSED*/
  2592.     static void
  2593. f_tempname(argvars, retvar)
  2594.     VAR argvars;
  2595.     VAR retvar;
  2596. {
  2597.     static int x = 'A';
  2598.     retvar->var_type = VAR_STRING;
  2599.     retvar->var_val.var_string = vim_tempname(x);
  2600.     /* advance 'x', so that there are at least 26 different names */
  2601.     if (x == 'Z')
  2602. x = 'A';
  2603.     else
  2604. ++x;
  2605. }
  2606. /*
  2607.  * "virtcol(string)" function
  2608.  */
  2609.     static void
  2610. f_virtcol(argvars, retvar)
  2611.     VAR argvars;
  2612.     VAR retvar;
  2613. {
  2614.     colnr_t vcol = 0;
  2615.     FPOS *fp;
  2616.     fp = var2fpos(&argvars[0]);
  2617.     if (fp != NULL)
  2618.     {
  2619. getvcol(curwin, fp, NULL, NULL, &vcol);
  2620. ++vcol;
  2621.     }
  2622.     retvar->var_val.var_number = vcol;
  2623. }
  2624. /*
  2625.  * "winbufnr(nr)" function
  2626.  */
  2627.     static void
  2628. f_winbufnr(argvars, retvar)
  2629.     VAR argvars;
  2630.     VAR retvar;
  2631. {
  2632.     WIN *wp;
  2633.     wp = find_win_by_nr(&argvars[0]);
  2634.     if (wp == NULL)
  2635. retvar->var_val.var_number = -1;
  2636.     else
  2637. retvar->var_val.var_number = wp->w_buffer->b_fnum;
  2638. }
  2639. /*
  2640.  * "winheight(nr)" function
  2641.  */
  2642.     static void
  2643. f_winheight(argvars, retvar)
  2644.     VAR argvars;
  2645.     VAR retvar;
  2646. {
  2647.     WIN *wp;
  2648.     wp = find_win_by_nr(&argvars[0]);
  2649.     if (wp == NULL)
  2650. retvar->var_val.var_number = -1;
  2651.     else
  2652. retvar->var_val.var_number = wp->w_height;
  2653. }
  2654. /*
  2655.  * "winnr()" function
  2656.  */
  2657. /* ARGSUSED */
  2658.     static void
  2659. f_winnr(argvars, retvar)
  2660.     VAR argvars;
  2661.     VAR retvar;
  2662. {
  2663.     int nr;
  2664.     WIN *wp;
  2665.     nr = 1;
  2666.     for (wp = firstwin; wp != curwin; wp = wp->w_next)
  2667. ++nr;
  2668.     retvar->var_val.var_number = nr;
  2669. }
  2670.     static WIN *
  2671. find_win_by_nr(vp)
  2672.     VAR vp;
  2673. {
  2674.     WIN *wp;
  2675.     int nr;
  2676.     nr = get_var_number(vp);
  2677.     if (nr == 0)
  2678. return curwin;
  2679.     for (wp = firstwin; wp != NULL; wp = wp->w_next)
  2680.     {
  2681. if (--nr <= 0)
  2682.     break;
  2683.     }
  2684.     return wp;
  2685. }
  2686. /*
  2687.  * Translate a String variable into a position (for col() and virtcol()).
  2688.  */
  2689.     static FPOS *
  2690. var2fpos(varp)
  2691.     VAR varp;
  2692. {
  2693.     char_u *name;
  2694.     name = get_var_string(varp);
  2695.     if (name[0] == '.') /* cursor */
  2696. return &curwin->w_cursor;
  2697.     if (name[0] == ''') /* mark */
  2698. return getmark(name[1], FALSE);
  2699.     return NULL;
  2700. }
  2701. /*
  2702.  * Get the lenght of an environment variable name.
  2703.  * Advance "arg" to the first character after the name.
  2704.  * Return 0 for error.
  2705.  */
  2706.     static int
  2707. get_env_len(arg)
  2708.     char_u **arg;
  2709. {
  2710.     char_u *p;
  2711.     int len;
  2712.     for (p = *arg; vim_isIDc(*p); ++p)
  2713. ;
  2714.     if (p == *arg)     /* no name found */
  2715. return 0;
  2716.     len = p - *arg;
  2717.     *arg = p;
  2718.     return len;
  2719. }
  2720. /*
  2721.  * Get the value of an environment variable.
  2722.  * "arg" points to the '$' before the env var name.
  2723.  * "arg" is advanced to the first character after the name.
  2724.  * Return NULL for failure.
  2725.  */
  2726.     char_u *
  2727. get_env_string(arg)
  2728.     char_u **arg;
  2729. {
  2730.     int     len;
  2731.     int     cc;
  2732.     char_u  *name;
  2733.     char_u  *s;
  2734.     ++*arg;
  2735.     name = *arg;
  2736.     len = get_env_len(arg);
  2737.     if (len == 0)
  2738. return NULL;
  2739.     cc = name[len];
  2740.     name[len] = NUL;
  2741.     s = mch_getenv(name);
  2742.     name[len] = cc;
  2743.     return s;
  2744. }
  2745. /*
  2746.  * Get the length of the name of a function or internal variable.
  2747.  * "arg" is advanced to the first non-white character after the name.
  2748.  * Return 0 if something is wrong.
  2749.  */
  2750.     static int
  2751. get_id_len(arg)
  2752.     char_u **arg;
  2753. {
  2754.     char_u *p;
  2755.     int len;
  2756.     /* Find the end of the name. */
  2757.     for (p = *arg; eval_isnamec(*p); ++p)
  2758. ;
  2759.     if (p == *arg)     /* no name found */
  2760. return 0;
  2761.     len = p - *arg;
  2762.     *arg = skipwhite(p);
  2763.     return len;
  2764. }
  2765.     static int
  2766. eval_isnamec(c)
  2767.     int     c;
  2768. {
  2769.     return (isalpha(c) || isdigit(c) || c == '_' || c == ':');
  2770. }
  2771. /*
  2772.  * Get the value of internal variable "name".
  2773.  * Return OK or FAIL.
  2774.  */
  2775.     static int
  2776. get_var_var(name, len, retvar)
  2777.     char_u *name;
  2778.     int len; /* length of "name" */
  2779.     VAR retvar; /* NULL when only checking existence */
  2780. {
  2781.     int ret = OK;
  2782.     int type = VAR_UNKNOWN;
  2783.     long number = 1;
  2784.     char_u *string = NULL;
  2785.     VAR v;
  2786.     int cc;
  2787.     cc = name[len];
  2788.     name[len] = NUL;
  2789.     /*
  2790.      * Check for built-in variables.
  2791.      */
  2792.     if (len == 7 && STRCMP(name, "version") == 0)
  2793.     {
  2794. type = VAR_NUMBER;
  2795. number = get_version();
  2796.     }
  2797.     else if (len == 5 && STRCMP(name, "count") == 0)
  2798.     {
  2799. type = VAR_NUMBER;
  2800. number = global_opnum;
  2801.     }
  2802.     else if (len == 11 && STRCMP(name, "shell_error") == 0)
  2803.     {
  2804. type = VAR_NUMBER;
  2805. number = call_shell_retval;
  2806.     }
  2807.     /*
  2808.      * Check for user-defined variables.
  2809.      */
  2810.     else
  2811.     {
  2812. v = find_var(name, FALSE);
  2813. if (v != NULL)
  2814. {
  2815.     type = v->var_type;
  2816.     number = v->var_val.var_number;
  2817.     string = v->var_val.var_string;
  2818. }
  2819.     }
  2820.     if (type == VAR_UNKNOWN)
  2821.     {
  2822. if (retvar != NULL)
  2823.     EMSG2("Undefined variable: %s", name);
  2824. ret = FAIL;
  2825.     }
  2826.     else if (retvar != NULL)
  2827.     {
  2828. retvar->var_type = type;
  2829. if (type == VAR_NUMBER)
  2830.     retvar->var_val.var_number = number;
  2831. else
  2832. {
  2833.     if (string != NULL)
  2834. string = vim_strsave(string);
  2835.     retvar->var_val.var_string = string;
  2836. }
  2837.     }
  2838.     name[len] = cc;
  2839.     return ret;
  2840. }
  2841. /*
  2842.  * Allocate memory for a variable, and make it emtpy (0 or NULL value).
  2843.  */
  2844.     static VAR
  2845. alloc_var()
  2846. {
  2847.     return (VAR)alloc_clear((unsigned)sizeof(var));
  2848. }
  2849. /*
  2850.  * Allocate memory for a variable, and assign a string to it.
  2851.  * The string "s" must have been allocated, it is consumed.
  2852.  * Return NULL for out of memory, the variable otherwise.
  2853.  */
  2854.     static VAR
  2855. alloc_string_var(s)
  2856.     char_u *s;
  2857. {
  2858.     VAR     retvar;
  2859.     retvar = alloc_var();
  2860.     if (retvar != NULL)
  2861.     {
  2862. retvar->var_type = VAR_STRING;
  2863. retvar->var_val.var_string = s;
  2864.     }
  2865.     else
  2866. vim_free(s);
  2867.     return retvar;
  2868. }
  2869. /*
  2870.  * Free the memory for a variable.
  2871.  */
  2872.     static void
  2873. free_var(varp)
  2874.     VAR     varp;
  2875. {
  2876.     if (varp != NULL)
  2877.     {
  2878. if (varp->var_type == VAR_STRING)
  2879.     vim_free(varp->var_val.var_string);
  2880. vim_free(varp->var_name);
  2881. vim_free(varp);
  2882.     }
  2883. }
  2884. /*
  2885.  * Free the memory for a variable value and set the value to NULL or 0.
  2886.  */
  2887.     static void
  2888. clear_var(varp)
  2889.     VAR     varp;
  2890. {
  2891.     if (varp != NULL)
  2892.     {
  2893. if (varp->var_type == VAR_STRING)
  2894. {
  2895.     vim_free(varp->var_val.var_string);
  2896.     varp->var_val.var_string = NULL;
  2897. }
  2898. else
  2899.     varp->var_val.var_number = 0;
  2900.     }
  2901. }
  2902. /*
  2903.  * Get the number value of a variable.
  2904.  * If it is a String variable, use vim_str2nr().
  2905.  */
  2906.     static long
  2907. get_var_number(varp)
  2908.     VAR varp;
  2909. {
  2910.     long n;
  2911.     if (varp->var_type == VAR_NUMBER)
  2912. return (long)(varp->var_val.var_number);
  2913.     else if (varp->var_val.var_string == NULL)
  2914. return 0L;
  2915.     else
  2916.     {
  2917. vim_str2nr(varp->var_val.var_string, NULL, NULL, TRUE, TRUE, &n, NULL);
  2918. return n;
  2919.     }
  2920. }
  2921. /*
  2922.  * Get the string value of a variable.
  2923.  * If it is a Number variable, the number is converted into a string.
  2924.  * get_var_string() uses a single, static buffer.  You can only use it once!
  2925.  * get_var_string_buf() uses a given buffer.
  2926.  * If the String variable has never been set, return an empty string.
  2927.  * Never returns NULL;
  2928.  */
  2929.     static char_u *
  2930. get_var_string(varp)
  2931.     VAR     varp;
  2932. {
  2933.     static char_u   mybuf[NUMBUFLEN];
  2934.     return get_var_string_buf(varp, mybuf);
  2935. }
  2936.     static char_u *
  2937. get_var_string_buf(varp, buf)
  2938.     VAR     varp;
  2939.     char_u  *buf;
  2940. {
  2941.     if (varp->var_type == VAR_NUMBER)
  2942.     {
  2943. sprintf((char *)buf, "%ld", (long)varp->var_val.var_number);
  2944. return buf;
  2945.     }
  2946.     else if (varp->var_val.var_string == NULL)
  2947. return (char_u *)"";
  2948.     else
  2949. return varp->var_val.var_string;
  2950. }
  2951. /*
  2952.  * Find variable "name" in the list of variables.
  2953.  * Return a pointer to it if found, NULL if not found.
  2954.  */
  2955.     static VAR
  2956. find_var(name, writing)
  2957.     char_u *name;
  2958.     int writing;
  2959. {
  2960.     int i;
  2961.     char_u *varname;
  2962.     struct growarray *gap;
  2963.     /* When not writing, check for function arguments "a:" */
  2964.     if (!writing && name[0] == 'a' && name[1] == ':')
  2965.     {
  2966. name += 2;
  2967. if (current_funccal == NULL)
  2968.     return NULL;
  2969. if (isdigit(*name))
  2970. {
  2971.     i = atol((char *)name);
  2972.     if (i == 0) /* a:0 */
  2973. return &current_funccal->a0_var;
  2974.     i += current_funccal->func->args.ga_len;
  2975.     if (i > current_funccal->argcount) /* a:999 */
  2976. return NULL;
  2977.     return &(current_funccal->argvars[i - 1]); /* a:1, a:2, etc. */
  2978. }
  2979. if (STRCMP(name, "firstline") == 0)
  2980.     return &(current_funccal->firstline);
  2981. if (STRCMP(name, "lastline") == 0)
  2982.     return &(current_funccal->lastline);
  2983. for (i = 0; i < current_funccal->func->args.ga_len; ++i)
  2984.     if (STRCMP(name, ((char_u **)
  2985.       (current_funccal->func->args.ga_data))[i]) == 0)
  2986.     return &(current_funccal->argvars[i]); /* a:name */
  2987. return NULL;
  2988.     }
  2989.     gap = find_var_ga(name, &varname);
  2990.     if (gap == NULL)
  2991. return NULL;
  2992.     for (i = gap->ga_len; --i >= 0; )
  2993. if (VAR_GAP_ENTRY(i, gap).var_name != NULL
  2994. && STRCMP(VAR_GAP_ENTRY(i, gap).var_name, varname) == 0)
  2995.     break;
  2996.     if (i < 0)
  2997. return NULL;
  2998.     return &VAR_GAP_ENTRY(i, gap);
  2999. }
  3000. /*
  3001.  * Find the growarray and start of name without ':' for a variable name.
  3002.  */
  3003.     static struct growarray *
  3004. find_var_ga(name, varname)
  3005.     char_u  *name;
  3006.     char_u  **varname;
  3007. {
  3008.     if (name[1] != ':')
  3009.     {
  3010. *varname = name;
  3011. if (current_funccal == NULL)
  3012.     return &variables; /* global variable */
  3013. return &current_funccal->l_vars; /* local function variable */
  3014.     }
  3015.     *varname = name + 2;
  3016.     if (*name == 'b') /* buffer variable */
  3017. return &curbuf->b_vars;
  3018.     if (*name == 'w') /* window variable */
  3019. return &curwin->w_vars;
  3020.     if (*name == 'g') /* global variable */
  3021. return &variables;
  3022.     if (*name == 'l' && current_funccal != NULL)/* local function variable */
  3023. return &current_funccal->l_vars;
  3024.     return NULL;
  3025. }
  3026. /*
  3027.  * Initialize internal variables for use.
  3028.  */
  3029.     void
  3030. var_init(gap)
  3031.     struct growarray *gap;
  3032. {
  3033.     ga_init2(gap, (int)sizeof(var), 4);
  3034. }
  3035. /*
  3036.  * Clean up a list of internal variables.
  3037.  */
  3038.     void
  3039. var_clear(gap)
  3040.     struct growarray *gap;
  3041. {
  3042.     int     i;
  3043.     for (i = gap->ga_len; --i >= 0; )
  3044. var_free_one(&VAR_GAP_ENTRY(i, gap));
  3045.     ga_clear(gap);
  3046. }
  3047.     static void
  3048. var_free_one(v)
  3049.     VAR     v;
  3050. {
  3051.     vim_free(v->var_name);
  3052.     v->var_name = NULL;
  3053.     if (v->var_type == VAR_STRING)
  3054. vim_free(v->var_val.var_string);
  3055.     v->var_val.var_string = NULL;
  3056. }
  3057. /*
  3058.  * List the value of one internal variable.
  3059.  */
  3060.     static void
  3061. list_one_var(v, prefix)
  3062.     VAR     v;
  3063.     char_u  *prefix;
  3064. {
  3065.     msg(prefix);
  3066.     msg_puts(v->var_name);
  3067.     msg_putchar(' ');
  3068.     msg_advance(22);
  3069.     if (v->var_type == VAR_NUMBER)
  3070. msg_putchar('#');
  3071.     else
  3072. msg_putchar(' ');
  3073.     msg_outtrans(get_var_string(v));
  3074. }
  3075. /*
  3076.  * Set variable "name" to value in "varp".
  3077.  * If the variable already exists, the value is updated.
  3078.  * Otherwise the variable is created.
  3079.  */
  3080.     static void
  3081. set_var(name, varp)
  3082.     char_u *name;
  3083.     VAR varp;
  3084. {
  3085.     int i;
  3086.     VAR v;
  3087.     char_u *varname;
  3088.     struct growarray *gap;
  3089.     v = find_var(name, TRUE);
  3090.     if (v != NULL)     /* existing variable, only need to free string */
  3091.     {
  3092. if (v->var_type == VAR_STRING)
  3093.     vim_free(v->var_val.var_string);
  3094.     }
  3095.     else     /* add a new variable */
  3096.     {
  3097. gap = find_var_ga(name, &varname);
  3098. if (gap == NULL)    /* illegal name */
  3099.     return;
  3100. /* Try to use an empty entry */
  3101. for (i = gap->ga_len; --i >= 0; )
  3102.     if (VAR_GAP_ENTRY(i, gap).var_name == NULL)
  3103. break;
  3104. if (i < 0)     /* need to allocated more room */
  3105. {
  3106.     if (ga_grow(gap, 1) == FAIL)
  3107. return;
  3108.     i = gap->ga_len;
  3109. }
  3110. v = &VAR_GAP_ENTRY(i, gap);
  3111. if ((v->var_name = vim_strsave(varname)) == NULL)
  3112.     return;
  3113. if (i == gap->ga_len)
  3114. {
  3115.     ++gap->ga_len;
  3116.     --gap->ga_room;
  3117. }
  3118.     }
  3119.     v->var_type = varp->var_type;
  3120.     if (varp->var_type == VAR_STRING)
  3121. v->var_val.var_string = vim_strsave(get_var_string(varp));
  3122.     else
  3123. v->var_val.var_number = varp->var_val.var_number;
  3124. }
  3125. /*
  3126.  * Implementation of
  3127.  * ":echo expr1 ..." print each argument separated with a space, add a
  3128.  * newline at the end.
  3129.  * ":echon expr1 ..." print each argument plain.
  3130.  */
  3131.     void
  3132. do_echo(eap, echo)
  3133.     EXARG *eap;
  3134.     int echo;     /* TRUE for ":echo" command, FALSE for ":echon" */
  3135. {
  3136.     char_u *arg = eap->arg;
  3137.     var retvar;
  3138.     char_u *p;
  3139.     int needclr = TRUE;
  3140.     int atstart = TRUE;
  3141.     if (eap->skip)
  3142. ++emsg_off;
  3143.     else if (echo)
  3144. msg_start();
  3145.     while (*arg != NUL && *arg != '|' && *arg != 'n')
  3146.     {
  3147. if (eval1(&arg, &retvar) == FAIL)
  3148.     break;
  3149. if (!eap->skip)
  3150. {
  3151.     if (atstart)
  3152. atstart = FALSE;
  3153.     else if (echo)
  3154. msg_puts_attr((char_u *)" ", echo_attr);
  3155.     for (p = get_var_string(&retvar); *p != NUL; ++p)
  3156. if (*p == 'n' || *p == 'r' || *p == TAB)
  3157. {
  3158.     if (*p != TAB && needclr)
  3159.     {
  3160. /* remove any text still there from the command */
  3161. msg_clr_eos();
  3162. needclr = FALSE;
  3163.     }
  3164.     msg_putchar_attr(*p, echo_attr);
  3165. }
  3166. else
  3167.     (void)msg_outtrans_len_attr(p, 1, echo_attr);
  3168. }
  3169. clear_var(&retvar);
  3170. arg = skipwhite(arg);
  3171.     }
  3172.     eap->nextcmd = check_nextcmd(arg);
  3173.     if (eap->skip)
  3174. --emsg_off;
  3175.     else
  3176.     {
  3177. /* remove text that may still be there from the command */
  3178. if (needclr)
  3179.     msg_clr_eos();
  3180. if (echo)
  3181.     msg_end();
  3182.     }
  3183. }
  3184. /*
  3185.  * Implementation of ":echohl {name}".
  3186.  */
  3187.     void
  3188. do_echohl(arg)
  3189.     char_u *arg;
  3190. {
  3191.     int id;
  3192.     id = syn_name2id(arg);
  3193.     if (id == 0)
  3194. echo_attr = 0;
  3195.     else
  3196. echo_attr = syn_id2attr(id);
  3197. }
  3198. /*
  3199.  * Implementation of
  3200.  * ":execute expr1 ..." execute the result of an expression.
  3201.  */
  3202.     void
  3203. do_execute(eap, getline, cookie)
  3204.     EXARG *eap;
  3205.     char_u *(*getline) __ARGS((int, void *, int));
  3206.     void *cookie; /* argument for getline() */
  3207. {
  3208.     char_u *arg = eap->arg;
  3209.     var retvar;
  3210.     int ret = OK;
  3211.     char_u *p;
  3212.     struct growarray ga;
  3213.     int len;
  3214.     ga_init2(&ga, 1, 80);
  3215.     if (eap->skip)
  3216. ++emsg_off;
  3217.     while (*arg != NUL && *arg != '|' && *arg != 'n')
  3218.     {
  3219. if (eval1(&arg, &retvar) == FAIL)
  3220. {
  3221.     ret = FAIL;
  3222.     break;
  3223. }
  3224. if (!eap->skip)
  3225. {
  3226.     p = get_var_string(&retvar);
  3227.     len = STRLEN(p);
  3228.     if (ga_grow(&ga, len + 2) == FAIL)
  3229.     {
  3230. clear_var(&retvar);
  3231. ret = FAIL;
  3232. break;
  3233.     }
  3234.     if (ga.ga_len)
  3235.     {
  3236. ((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
  3237. --ga.ga_room;
  3238.     }
  3239.     STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
  3240.     ga.ga_room -= len;
  3241.     ga.ga_len += len;
  3242. }
  3243. clear_var(&retvar);
  3244. arg = skipwhite(arg);
  3245.     }
  3246.     if (ret != FAIL && ga.ga_data != NULL)
  3247. do_cmdline((char_u *)ga.ga_data,
  3248.  getline, cookie, DOCMD_NOWAIT|DOCMD_VERBOSE);
  3249.     ga_clear(&ga);
  3250.     if (eap->skip)
  3251. --emsg_off;
  3252.     eap->nextcmd = check_nextcmd(arg);
  3253. }
  3254.     static char_u *
  3255. find_option_end(p)
  3256.     char_u  *p;
  3257. {
  3258.     while (isalnum(*p) || *p == '_')
  3259. ++p;
  3260.     return p;
  3261. }
  3262. /*
  3263.  * Handle the ":function" command.
  3264.  * "getline" can be NULL, in which case a line is obtained from the user.
  3265.  */
  3266.     void
  3267. do_function(eap, getline, cookie)
  3268.     EXARG *eap;
  3269.     char_u *(*getline) __ARGS((int, void *, int));
  3270.     void *cookie; /* argument for getline() */
  3271. {
  3272.     char_u *theline;
  3273.     int j;
  3274.     int c;
  3275.     char_u *name;
  3276.     char_u *nameend;
  3277.     char_u *p;
  3278.     char_u *arg;
  3279.     struct growarray newargs;
  3280.     struct growarray newlines;
  3281.     int varargs = FALSE;
  3282.     int mustend = FALSE;
  3283.     int flags = 0;
  3284.     struct ufunc *fp;
  3285.     /*
  3286.      * ":function" without argument: list functions.
  3287.      */
  3288.     if (*eap->arg == NUL)
  3289.     {
  3290. if (!eap->skip)
  3291.     for (fp = firstfunc; fp != NULL; fp = fp->next)
  3292. list_func_head(fp);
  3293. return;
  3294.     }
  3295.     if (!isupper(*eap->arg))
  3296.     {
  3297. EMSG2("Function name must start with a capital: %s", eap->arg);
  3298. return;
  3299.     }
  3300.     /*
  3301.      * ":function func" with only function name: list function.
  3302.      */
  3303.     if (vim_strchr(eap->arg, '(') == NULL)
  3304.     {
  3305. if (!eap->skip)
  3306. {
  3307.     fp = find_func(eap->arg);
  3308.     if (fp != NULL)
  3309.     {
  3310. list_func_head(fp);
  3311. for (j = 0; j < fp->lines.ga_len; ++j)
  3312. {
  3313.     msg_putchar('n');
  3314.     msg_prt_line(FUNCLINE(fp, j));
  3315. }
  3316. MSG("endfunction");
  3317.     }
  3318.     else
  3319. EMSG2("Undefined function: %s", eap->arg);
  3320. }
  3321. return;
  3322.     }
  3323.     /*
  3324.      * ":function name(arg1, arg2)" Define function.
  3325.      */
  3326.     name = eap->arg;
  3327.     for (p = name; isalpha(*p) || isdigit(*p) || *p == '_'; ++p)
  3328. ;
  3329.     if (p == name)
  3330.     {
  3331. EMSG("Function name required");
  3332. return;
  3333.     }
  3334.     nameend = p;
  3335.     p = skipwhite(p);
  3336.     if (*p != '(')
  3337.     {
  3338. EMSG2("Missing '(': %s", name);
  3339. return;
  3340.     }
  3341.     p = skipwhite(p + 1);
  3342.     ga_init2(&newargs, (int)sizeof(char_u *), 3);
  3343.     ga_init2(&newlines, (int)sizeof(char_u *), 3);
  3344.     /*
  3345.      * Isolate the arguments: "arg1, arg2, ...)"
  3346.      */
  3347.     while (*p != ')')
  3348.     {
  3349. if (p[0] == '.' && p[1] == '.' && p[2] == '.')
  3350. {
  3351.     varargs = TRUE;
  3352.     p += 3;
  3353.     mustend = TRUE;
  3354. }
  3355. else
  3356. {
  3357.     arg = p;
  3358.     while (isalpha(*p) || isdigit(*p) || *p == '_')
  3359. ++p;
  3360.     if (arg == p || isdigit(*arg))
  3361.     {
  3362. EMSG2("Illegal argument: %s", arg);
  3363. goto erret;
  3364.     }
  3365.     if (ga_grow(&newargs, 1) == FAIL)
  3366. goto erret;
  3367.     c = *p;
  3368.     *p = NUL;
  3369.     arg = vim_strsave(arg);
  3370.     if (arg == NULL)
  3371. goto erret;
  3372.     ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
  3373.     *p = c;
  3374.     newargs.ga_len++;
  3375.     newargs.ga_room--;
  3376.     if (*p == ',')
  3377. ++p;
  3378.     else
  3379. mustend = TRUE;
  3380. }
  3381. p = skipwhite(p);
  3382. if (mustend && *p != ')')
  3383. {
  3384.     EMSG2(e_invarg2, eap->arg);
  3385.     goto erret;
  3386. }
  3387.     }
  3388.     ++p; /* skip the ')' */
  3389.     /* find extra arguments "range" and "abort" */
  3390.     for (;;)
  3391.     {
  3392. p = skipwhite(p);
  3393. if (STRNCMP(p, "range", 5) == 0)
  3394. {
  3395.     flags |= FC_RANGE;
  3396.     p += 5;
  3397. }
  3398. else if (STRNCMP(p, "abort", 5) == 0)
  3399. {
  3400.     flags |= FC_ABORT;
  3401.     p += 5;
  3402. }
  3403. else
  3404.     break;
  3405.     }
  3406.     if (*p != NUL && *p != '"' && *p != 'n')
  3407.     {
  3408. EMSG(e_trailing);
  3409. goto erret;
  3410.     }
  3411.     /*
  3412.      * Read the body of the function, until ":endfunction" is found.
  3413.      */
  3414.     if (KeyTyped)
  3415.     {
  3416. msg_putchar('n');     /* don't overwrite the function name */
  3417. cmdline_row = msg_row;
  3418.     }
  3419.     for (;;)
  3420.     {
  3421. msg_scroll = TRUE;
  3422. need_wait_return = FALSE;
  3423. if (getline == NULL)
  3424.     theline = getcmdline(':', 0L, 2);
  3425. else
  3426.     theline = getline(':', cookie, 2);
  3427. lines_left = Rows - 1;
  3428. if (theline == NULL)
  3429.     goto erret;
  3430. for (p = theline; vim_iswhite(*p) || *p == ':'; ++p)
  3431.     ;
  3432. if (STRNCMP(p, "endf", 4) == 0)
  3433. {
  3434.     vim_free(theline);
  3435.     break;
  3436. }
  3437. if (ga_grow(&newlines, 1) == FAIL)
  3438.     goto erret;
  3439. ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline;
  3440. newlines.ga_len++;
  3441. newlines.ga_room--;
  3442.     }
  3443.     if (eap->skip)
  3444. goto erret;
  3445.     /*
  3446.      * If there are no errors, add the function
  3447.      */
  3448.     *nameend = NUL;
  3449.     fp = find_func(name);
  3450.     if (fp != NULL)
  3451.     {
  3452. if (!eap->forceit)
  3453. {
  3454.     EMSG2("Function %s already exists, use ! to replace", name);
  3455.     goto erret;
  3456. }
  3457. /* redefine existing function */
  3458. ga_clear_strings(&(fp->args));
  3459. ga_clear_strings(&(fp->lines));
  3460.     }
  3461.     else
  3462.     {
  3463. fp = (struct ufunc *)alloc((unsigned)sizeof(struct ufunc));
  3464. if (fp == NULL)
  3465.     goto erret;
  3466. name = vim_strsave(name);
  3467. if (name == NULL)
  3468. {
  3469.     vim_free(fp);
  3470.     goto erret;
  3471. }
  3472. /* insert the new function in the function list */
  3473. fp->next = firstfunc;
  3474. firstfunc = fp;
  3475. fp->name = name;
  3476.     }
  3477.     fp->args = newargs;
  3478.     fp->lines = newlines;
  3479.     fp->varargs = varargs;
  3480.     fp->flags = flags;
  3481.     return;
  3482. erret:
  3483.     ga_clear_strings(&newargs);
  3484.     ga_clear_strings(&newlines);
  3485. }
  3486. /*
  3487.  * List the head of the function: "name(arg1, arg2)".
  3488.  */
  3489.     static void
  3490. list_func_head(fp)
  3491.     struct ufunc *fp;
  3492. {
  3493.     int j;
  3494.     MSG("function ");
  3495.     msg_puts(fp->name);
  3496.     msg_putchar('(');
  3497.     for (j = 0; j < fp->args.ga_len; ++j)
  3498.     {
  3499. if (j)
  3500.     MSG_PUTS(", ");
  3501. msg_puts(FUNCARG(fp, j));
  3502.     }
  3503.     if (fp->varargs)
  3504.     {
  3505. if (j)
  3506.     MSG_PUTS(", ");
  3507. MSG_PUTS("...");
  3508.     }
  3509.     msg_putchar(')');
  3510. }
  3511. /*
  3512.  * Find a function by name, return its index in ufuncs.
  3513.  * Return -1 for unknown function.
  3514.  */
  3515.     static struct ufunc *
  3516. find_func(name)
  3517.     char_u *name;
  3518. {
  3519.     struct ufunc *fp;
  3520.     for (fp = firstfunc; fp != NULL; fp = fp->next)
  3521. if (STRCMP(name, fp->name) == 0)
  3522.     break;
  3523.     return fp;
  3524. }
  3525. /*
  3526.  * Handle ":delfunction {name}".
  3527.  */
  3528.     void
  3529. do_delfunction(arg)
  3530.     char_u *arg;
  3531. {
  3532.     struct ufunc *fp, *pfp;
  3533.     fp = find_func(arg);
  3534.     if (fp == NULL)
  3535.     {
  3536. EMSG2("Undefined function: %s", arg);
  3537. return;
  3538.     }
  3539.     /* clear this function */
  3540.     vim_free(fp->name);
  3541.     ga_clear_strings(&(fp->args));
  3542.     ga_clear_strings(&(fp->lines));
  3543.     /* remove the function from the function list */
  3544.     if (firstfunc == fp)
  3545. firstfunc = fp->next;
  3546.     else
  3547. for (pfp = firstfunc; pfp != NULL; pfp = pfp->next)
  3548.     if (pfp->next == fp)
  3549.     {
  3550. pfp->next = fp->next;
  3551. break;
  3552.     }
  3553. }
  3554. /*
  3555.  * Call a user function.
  3556.  */
  3557.     static void
  3558. call_func(fp, argcount, argvars, retvar, firstline, lastline)
  3559.     struct ufunc *fp; /* pointer to function */
  3560.     int argcount; /* nr of args */
  3561.     VAR argvars; /* arguments */
  3562.     VAR retvar; /* return value */
  3563.     linenr_t firstline; /* first line of range */
  3564.     linenr_t lastline; /* last line of range */
  3565. {
  3566.     char_u *save_sourcing_name;
  3567.     int save_redrawing = RedrawingDisabled;
  3568.     struct funccall fc;
  3569.     struct funccall *save_fcp = current_funccal;
  3570.     int save_did_emsg;
  3571.     static int depth = 0;
  3572.     /* If depth of calling is getting too high, don't execute the function */
  3573.     if (depth >= p_mfd)
  3574.     {
  3575. EMSG("Function call depth is higher than 'maxfuncdepth'");
  3576. retvar->var_type = VAR_NUMBER;
  3577. retvar->var_val.var_number = -1;
  3578. return;
  3579.     }
  3580.     ++depth;
  3581.     line_breakcheck(); /* check for CTRL-C hit */
  3582.     /* set local variables */
  3583.     var_init(&fc.l_vars);
  3584.     fc.func = fp;
  3585.     fc.argcount = argcount;
  3586.     fc.argvars = argvars;
  3587.     fc.retvar = retvar;
  3588.     retvar->var_val.var_number = 0;
  3589.     fc.linenr = 0;
  3590.     fc.a0_var.var_type = VAR_NUMBER;
  3591.     fc.a0_var.var_val.var_number = argcount - fp->args.ga_len;
  3592.     fc.a0_var.var_name = NULL;
  3593.     current_funccal = &fc;
  3594.     fc.firstline.var_type = VAR_NUMBER;
  3595.     fc.firstline.var_val.var_number = firstline;
  3596.     fc.firstline.var_name = NULL;
  3597.     fc.lastline.var_type = VAR_NUMBER;
  3598.     fc.lastline.var_val.var_number = lastline;
  3599.     fc.lastline.var_name = NULL;
  3600.     /* Don't redraw while executing the function. */
  3601.     RedrawingDisabled = TRUE;
  3602.     save_sourcing_name = sourcing_name;
  3603.     sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0
  3604. : STRLEN(save_sourcing_name)) + STRLEN(fp->name) + 10));
  3605.     if (sourcing_name != NULL)
  3606.     {
  3607. if (save_sourcing_name != NULL
  3608.   && STRNCMP(save_sourcing_name, "function ", 9) == 0)
  3609.     sprintf((char *)sourcing_name, "%s->", save_sourcing_name);
  3610. else
  3611.     STRCPY(sourcing_name, "function ");
  3612. STRCAT(sourcing_name, fp->name);
  3613.     }
  3614.     save_did_emsg = did_emsg;
  3615.     did_emsg = FALSE;
  3616.     /* call do_cmdline() to execute the lines */
  3617.     do_cmdline(NULL, get_func_line, (void *)&fc,
  3618.      DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
  3619.     RedrawingDisabled = save_redrawing;
  3620.     vim_free(sourcing_name);
  3621.     sourcing_name = save_sourcing_name;
  3622.     /* when the function was aborted because of an error, return -1 */
  3623.     if (did_emsg && (fp->flags & FC_ABORT))
  3624.     {
  3625. clear_var(retvar);
  3626. retvar->var_type = VAR_NUMBER;
  3627. retvar->var_val.var_number = -1;
  3628.     }
  3629.     did_emsg |= save_did_emsg;
  3630.     current_funccal = save_fcp;
  3631.     var_clear(&fc.l_vars); /* free all local variables */
  3632.     --depth;
  3633. }
  3634. /*
  3635.  * Save the current function call pointer, and set it to NULL.
  3636.  * Used when executing autocommands and for ":source".
  3637.  */
  3638.     void *
  3639. save_funccal()
  3640. {
  3641.     struct funccall *fc;
  3642.     fc = current_funccal;
  3643.     current_funccal = NULL;
  3644.     return (void *)fc;
  3645. }
  3646.     void
  3647. restore_funccal(fc)
  3648.     void *fc;
  3649. {
  3650.     current_funccal = (struct funccall *)fc;
  3651. }
  3652. /*
  3653.  * Handle ":return [expr]".
  3654.  */
  3655.     void
  3656. do_return(eap)
  3657.     EXARG *eap;
  3658. {
  3659.     char_u *arg = eap->arg;
  3660.     var retvar;
  3661.     if (current_funccal == NULL)
  3662.     {
  3663. EMSG(":return not inside a function");
  3664. return;
  3665.     }
  3666.     if (eap->skip)
  3667. ++emsg_off;
  3668.     else
  3669. current_funccal->linenr = -1;
  3670.     if (*arg != NUL && *arg != '|' && *arg != 'n')
  3671.     {
  3672. if (eval1(&arg, &retvar) != FAIL)
  3673. {
  3674.     if (!eap->skip)
  3675.     {
  3676. clear_var(current_funccal->retvar);
  3677. *current_funccal->retvar = retvar;
  3678.     }
  3679.     else
  3680. clear_var(&retvar);
  3681. }
  3682.     }
  3683.     /* when skipping, advance to the next command in this line.  When not
  3684.      * skipping, ignore the rest of the line.  Following lines will be ignored
  3685.      * by get_func_line(). */
  3686.     if (eap->skip)
  3687.     {
  3688. --emsg_off;
  3689. eap->nextcmd = check_nextcmd(arg);
  3690.     }
  3691.     else
  3692. eap->nextcmd = NULL;
  3693. }
  3694. /*
  3695.  * Get next function line.
  3696.  * Called by do_cmdline() to get the next line.
  3697.  * Returns allocated string, or NULL for end of function.
  3698.  */
  3699. /* ARGSUSED */
  3700.     char_u *
  3701. get_func_line(c, cookie, indent)
  3702.     int     c;     /* not used */
  3703.     void    *cookie;
  3704.     int     indent;     /* not used */
  3705. {
  3706.     struct funccall  *fcp = (struct funccall *)cookie;
  3707.     char_u     *retval;
  3708.     struct growarray *gap;  /* growarray with function lines */
  3709.     gap = &fcp->func->lines;
  3710.     if ((fcp->func->flags & FC_ABORT) && did_emsg)
  3711. retval = NULL;
  3712.     else if (fcp->linenr < 0 || fcp->linenr >= gap->ga_len)
  3713. retval = NULL;
  3714.     else
  3715. retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
  3716.     if (p_verbose >= 15)
  3717.     {
  3718. msg_scroll = TRUE;     /* always scroll up, don't overwrite */
  3719. if (retval == NULL)
  3720.     msg((char_u *)"function returning");
  3721. else
  3722.     smsg((char_u *)"function line %s", retval);
  3723. msg_puts((char_u *)"n");   /* don't overwrite this either */
  3724. cmdline_row = msg_row;
  3725.     }
  3726.     return retval;
  3727. }
  3728. /*
  3729.  * Return TRUE if the currently active function should be ended, because a
  3730.  * return was encountered or an error occured.  Used inside a ":while".
  3731.  */
  3732.     int
  3733. func_has_ended(cookie)
  3734.     void    *cookie;
  3735. {
  3736.     struct funccall  *fcp = (struct funccall *)cookie;
  3737.     return (((fcp->func->flags & FC_ABORT) && did_emsg) || fcp->linenr < 0);
  3738. }
  3739. /*
  3740.  * return TRUE if cookie indicates a function which "abort"s on errors.
  3741.  */
  3742.     int
  3743. func_has_abort(cookie)
  3744.     void    *cookie;
  3745. {
  3746.     return ((struct funccall *)cookie)->func->flags & FC_ABORT;
  3747. }
  3748. #endif /* WANT_EVAL */
  3749. #if defined(WANT_MODIFY_FNAME) || defined(WANT_EVAL)
  3750. /*
  3751.  * Adjust a filename, according to a string of modifiers.
  3752.  * *fnamep must be NUL terminated when called.  When returning, the length is
  3753.  * determined by *fnamelen.
  3754.  * Returns valid flags.
  3755.  * When there is an error, *fnamep is set to NULL.
  3756.  */
  3757.     int
  3758. modify_fname(src, usedlen, fnamep, bufp, fnamelen)
  3759.     char_u *src; /* string with modifiers */
  3760.     int *usedlen; /* characters after src that are used */
  3761.     char_u **fnamep; /* file name so far */
  3762.     char_u **bufp; /* buffer for allocated file name or NULL */
  3763.     int *fnamelen; /* length of fnamep */
  3764. {
  3765.     int valid = 0;
  3766.     char_u *tail;
  3767.     char_u *s, *p;
  3768.     char_u dirname[MAXPATHL];
  3769. repeat:
  3770.     /* ":p" - full path/file_name */
  3771.     if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p')
  3772.     {
  3773. valid |= VALID_PATH;
  3774. *usedlen += 2;
  3775. *fnamep = FullName_save(*fnamep, FALSE);
  3776. vim_free(*bufp); /* free any allocated file name */
  3777. *bufp = *fnamep;
  3778. if (*fnamep == NULL)
  3779.     return -1;
  3780.     }
  3781.     /* ":." - path relative to the current directory */
  3782.     if (src[*usedlen] == ':' && src[*usedlen + 1] == '.')
  3783.     {
  3784. *usedlen += 2;
  3785. /* Need full path first (use force to remove a "~/") */
  3786. p = FullName_save(*fnamep, **fnamep == '~');
  3787. if (p != NULL)
  3788. {
  3789.     mch_dirname(dirname, MAXPATHL);
  3790.     s = shorten_fname(p, dirname);
  3791.     if (s != NULL)
  3792.     {
  3793. *fnamep = s;
  3794. vim_free(*bufp); /* free any allocated file name */
  3795. *bufp = p;
  3796.     }
  3797.     else
  3798. vim_free(p);
  3799. }
  3800.     }
  3801.     /* ":~" - path relative to the home directory */
  3802.     if (src[*usedlen] == ':' && src[*usedlen + 1] == '~')
  3803.     {
  3804. *usedlen += 2;
  3805. /* Need full path first */
  3806. p = FullName_save(*fnamep, FALSE);
  3807. if (p != NULL)
  3808. {
  3809.     home_replace(NULL, p, dirname, MAXPATHL, TRUE);
  3810.     /* Only replace it when it starts with '~' */
  3811.     if (*dirname == '~')
  3812.     {
  3813. s = vim_strsave(dirname);
  3814. if (s != NULL)
  3815. {
  3816.     *fnamep = s;
  3817.     vim_free(*bufp);
  3818.     *bufp = s;
  3819. }
  3820.     }
  3821.     vim_free(p);
  3822. }
  3823.     }
  3824.     tail = gettail(*fnamep);
  3825.     *fnamelen = STRLEN(*fnamep);
  3826.     /* ":h" - head, remove "/file_name", can be repeated  */
  3827.     /* Don't remove the first "/" or "c:" */
  3828.     while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h')
  3829.     {
  3830. valid |= VALID_HEAD;
  3831. *usedlen += 2;
  3832. s = get_past_head(*fnamep);
  3833. while (tail > s && vim_ispathsep(tail[-1]))
  3834.     --tail;
  3835. *fnamelen = tail - *fnamep;
  3836. while (tail > s && !vim_ispathsep(tail[-1]))
  3837.     --tail;
  3838.     }
  3839.     /* ":t" - tail, just the basename */
  3840.     if (src[*usedlen] == ':' && src[*usedlen + 1] == 't')
  3841.     {
  3842. *usedlen += 2;
  3843. *fnamelen -= tail - *fnamep;
  3844. *fnamep = tail;
  3845.     }
  3846.     /* ":e" - extension, can be repeated */
  3847.     /* ":r" - root, without extension, can be repeated */
  3848.     while (src[*usedlen] == ':'
  3849.     && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r'))
  3850.     {
  3851. /* find a '.' in the tail:
  3852.  * - for second :e: before the current fname
  3853.  * - otherwise: The last '.'
  3854.  */
  3855. if (src[*usedlen + 1] == 'e' && *fnamep > tail)
  3856.     s = *fnamep - 2;
  3857. else
  3858.     s = *fnamep + *fnamelen - 1;
  3859. for ( ; s > tail; --s)
  3860.     if (s[0] == '.')
  3861. break;
  3862. if (src[*usedlen + 1] == 'e') /* :e */
  3863. {
  3864.     if (s > tail)
  3865.     {
  3866. *fnamelen += *fnamep - (s + 1);
  3867. *fnamep = s + 1;
  3868.     }
  3869.     else if (*fnamep <= tail)
  3870. *fnamelen = 0;
  3871. }
  3872. else /* :r */
  3873. {
  3874.     if (s > tail) /* remove one extension */
  3875. *fnamelen = s - *fnamep;
  3876. }
  3877. *usedlen += 2;
  3878.     }
  3879.     /* ":s?pat?foo?" - substitute */
  3880.     /* ":gs?pat?foo?" - global substitute */
  3881.     if (src[*usedlen] == ':'
  3882.     && (src[*usedlen + 1] == 's'
  3883. || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's')))
  3884.     {
  3885. char_u     *str;
  3886. char_u     *pat;
  3887. char_u     *sub;
  3888. int     sep;
  3889. char_u     *flags;
  3890. int     didit = FALSE;
  3891. flags = (char_u *)"";
  3892. s = src + *usedlen + 2;
  3893. if (src[*usedlen + 1] == 'g')
  3894. {
  3895.     flags = (char_u *)"g";
  3896.     ++s;
  3897. }
  3898. sep = *s++;
  3899. if (sep)
  3900. {
  3901.     /* find end of pattern */
  3902.     p = vim_strchr(s, sep);
  3903.     if (p != NULL)
  3904.     {
  3905. pat = vim_strnsave(s, (int)(p - s));
  3906. if (pat != NULL)
  3907. {
  3908.     s = p + 1;
  3909.     /* find end of substitution */
  3910.     p = vim_strchr(s, sep);
  3911.     if (p != NULL)
  3912.     {
  3913. sub = vim_strnsave(s, (int)(p - s));
  3914. str = vim_strnsave(*fnamep, *fnamelen);
  3915. if (sub != NULL && str != NULL)
  3916. {
  3917.     *usedlen = p + 1 - src;
  3918.     s = do_string_sub(str, pat, sub, flags);
  3919.     if (s != NULL)
  3920.     {
  3921. *fnamep = s;
  3922. *fnamelen = STRLEN(s);
  3923. vim_free(*bufp);
  3924. *bufp = s;
  3925. didit = TRUE;
  3926.     }
  3927. }
  3928. vim_free(sub);
  3929. vim_free(str);
  3930.     }
  3931.     vim_free(pat);
  3932. }
  3933.     }
  3934.     /* after using ":s", repeat all the modifiers */
  3935.     if (didit)
  3936. goto repeat;
  3937. }
  3938.     }
  3939.     return valid;
  3940. }
  3941. /*
  3942.  * Perform a substitution on "str" with pattern "pat" and substitute "sub".
  3943.  * "flags" can be "g" to do a global substitute.
  3944.  * Returns an allocated string, NULL for error.
  3945.  */
  3946.     char_u *
  3947. do_string_sub(str, pat, sub, flags)
  3948.     char_u *str;
  3949.     char_u *pat;
  3950.     char_u *sub;
  3951.     char_u *flags;
  3952. {
  3953.     int sublen;
  3954.     vim_regexp *prog;
  3955.     int i;
  3956.     int do_all;
  3957.     char_u *tail;
  3958.     struct growarray ga;
  3959.     char_u *ret;
  3960.     ga_init2(&ga, 1, 200);
  3961.     do_all = (flags[0] == 'g');
  3962.     reg_ic = p_ic;
  3963.     prog = vim_regcomp(pat, TRUE);
  3964.     if (prog != NULL)
  3965.     {
  3966. tail = str;
  3967. while (vim_regexec(prog, tail, tail == str))
  3968. {
  3969.     /*
  3970.      * Get some space for a temporary buffer to do the substitution
  3971.      * into.  It will contain:
  3972.      * - The text up to where the match is.
  3973.      * - The substituted text.
  3974.      * - The text after the match.
  3975.      */
  3976.     sublen = vim_regsub(prog, sub, tail, FALSE, TRUE);
  3977.     if (ga_grow(&ga, (int)(STRLEN(tail) + sublen -
  3978.   (prog->endp[0] - prog->startp[0]))) == FAIL)
  3979.     {
  3980. ga_clear(&ga);
  3981. break;
  3982.     }
  3983.     /* copy the text up to where the match is */
  3984.     i = prog->startp[0] - tail;
  3985.     mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
  3986.     /* add the substituted text */
  3987.     (void)vim_regsub(prog, sub, (char_u *)ga.ga_data + ga.ga_len + i,
  3988.   TRUE, TRUE);
  3989.     ga.ga_len += i + sublen - 1;
  3990.     ga.ga_room -= i + sublen - 1;
  3991.     /* avoid getting stuck on a match with an empty string */
  3992.     if (tail == prog->endp[0])
  3993.     {
  3994. *((char_u *)ga.ga_data + ga.ga_len) = *tail++;
  3995. ++ga.ga_len;
  3996. --ga.ga_room;
  3997.     }
  3998.     else
  3999.     {
  4000. tail = prog->endp[0];
  4001. if (*tail == NUL)
  4002.     break;
  4003.     }
  4004.     if (!do_all)
  4005. break;
  4006. }
  4007. if (ga.ga_data != NULL)
  4008.     STRCPY((char *)ga.ga_data + ga.ga_len, tail);
  4009. vim_free(prog);
  4010.     }
  4011.     ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
  4012.     ga_clear(&ga);
  4013.     return ret;
  4014. }
  4015. #endif /* defined(WANT_MODIFY_FNAME) || defined(WANT_EVAL) */