]> granicus.if.org Git - vim/commitdiff
patch 7.4.1999 v7.4.1999
authorBram Moolenaar <Bram@vim.org>
Thu, 7 Jul 2016 21:04:18 +0000 (23:04 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 7 Jul 2016 21:04:18 +0000 (23:04 +0200)
Problem:    evalcmd() doesn't work recursively.
Solution:   Use redir_evalcmd instead of redir_vname.

src/eval.c
src/globals.h
src/message.c
src/proto/eval.pro
src/testdir/test_evalcmd.vim
src/version.c

index 74ed263d51192e969ee245b9ca664bd9968dfd7c..445b6b91c45cee7ced93cfe33d1014afb1fb13f1 100644 (file)
@@ -11345,6 +11345,28 @@ f_eval(typval_T *argvars, typval_T *rettv)
        EMSG(_(e_trailing));
 }
 
+static garray_T        redir_evalcmd_ga;
+
+/*
+ * Append "value[value_len]" to the evalcmd() output.
+ */
+    void
+evalcmd_redir_str(char_u *value, int value_len)
+{
+    int                len;
+
+    if (value_len == -1)
+       len = (int)STRLEN(value);       /* Append the entire string */
+    else
+       len = value_len;                /* Append only "value_len" characters */
+    if (ga_grow(&redir_evalcmd_ga, len) == OK)
+    {
+       mch_memmove((char *)redir_evalcmd_ga.ga_data
+                                      + redir_evalcmd_ga.ga_len, value, len);
+       redir_evalcmd_ga.ga_len += len;
+    }
+}
+
 /*
  * "evalcmd()" function
  */
@@ -11352,6 +11374,9 @@ f_eval(typval_T *argvars, typval_T *rettv)
 f_evalcmd(typval_T *argvars, typval_T *rettv)
 {
     char_u     *s;
+    int                save_msg_silent = msg_silent;
+    int                save_redir_evalcmd = redir_evalcmd;
+    garray_T   save_ga;
 
     rettv->vval.v_string = NULL;
     rettv->v_type = VAR_STRING;
@@ -11359,20 +11384,20 @@ f_evalcmd(typval_T *argvars, typval_T *rettv)
     s = get_tv_string_chk(&argvars[0]);
     if (s != NULL)
     {
-       redir_vname = TRUE;
-       redir_lval = (lval_T *)&redir_lval;
-       ga_init2(&redir_ga, (int)sizeof(char), 500);
+       if (redir_evalcmd)
+           save_ga = redir_evalcmd_ga;
+       ga_init2(&redir_evalcmd_ga, (int)sizeof(char), 500);
+       redir_evalcmd = TRUE;
 
-       if (do_cmdline_cmd(s) == OK)
-           rettv->vval.v_string = redir_ga.ga_data;
-       else
-           vim_free(redir_ga.ga_data);
+       ++msg_silent;
+       do_cmdline_cmd(s);
+       rettv->vval.v_string = redir_evalcmd_ga.ga_data;
+       msg_silent = save_msg_silent;
 
-       redir_ga.ga_data = NULL;
-       redir_vname = FALSE;
-       redir_lval = NULL;
+       redir_evalcmd = save_redir_evalcmd;
+       if (redir_evalcmd)
+           redir_evalcmd_ga = save_ga;
     }
-
 }
 
 /*
index f14cb89a923bf1d9d4bb8198380629e89636350b..97711164abd8a4591a43353db309e15625d0c569 100644 (file)
@@ -1106,6 +1106,7 @@ EXTERN FILE *redir_fd INIT(= NULL);       /* message redirection file */
 #ifdef FEAT_EVAL
 EXTERN int  redir_reg INIT(= 0);       /* message redirection register */
 EXTERN int  redir_vname INIT(= 0);     /* message redirection variable */
+EXTERN int  redir_evalcmd INIT(= 0);   /* evalcmd() redirection */
 #endif
 
 #ifdef FEAT_LANGMAP
index b86c88675096390e05773569b564ef69d9a4830b..f793ed4143ad4cd670b34b5ea89a6c9337922d63 100644 (file)
@@ -3063,7 +3063,9 @@ redir_write(char_u *str, int maxlen)
            while (cur_col < msg_col)
            {
 #ifdef FEAT_EVAL
-               if (redir_reg)
+               if (redir_evalcmd)
+                   evalcmd_redir_str((char_u *)" ", -1);
+               else if (redir_reg)
                    write_reg_contents(redir_reg, (char_u *)" ", -1, TRUE);
                else if (redir_vname)
                    var_redir_str((char_u *)" ", -1);
@@ -3078,9 +3080,11 @@ redir_write(char_u *str, int maxlen)
        }
 
 #ifdef FEAT_EVAL
-       if (redir_reg)
+       if (redir_evalcmd)
+           evalcmd_redir_str(s, maxlen);
+       else if (redir_reg)
            write_reg_contents(redir_reg, s, maxlen, TRUE);
-       if (redir_vname)
+       else if (redir_vname)
            var_redir_str(s, maxlen);
 #endif
 
@@ -3088,7 +3092,7 @@ redir_write(char_u *str, int maxlen)
        while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
        {
 #ifdef FEAT_EVAL
-           if (!redir_reg && !redir_vname)
+           if (!redir_reg && !redir_vname && !redir_evalcmd)
 #endif
                if (redir_fd != NULL)
                    putc(*s, redir_fd);
@@ -3113,7 +3117,7 @@ redirecting(void)
 {
     return redir_fd != NULL || *p_vfile != NUL
 #ifdef FEAT_EVAL
-                         || redir_reg || redir_vname
+                         || redir_reg || redir_vname || redir_evalcmd
 #endif
                                       ;
 }
index 4ff063e72cd51083a862fbfa4c323610347c4333..28edd782c13a63d9bb5083166d0286b63397c372 100644 (file)
@@ -81,12 +81,14 @@ int dict_add_list(dict_T *d, char *key, list_T *list);
 dictitem_T *dict_find(dict_T *d, char_u *key, int len);
 char_u *get_dict_string(dict_T *d, char_u *key, int save);
 varnumber_T get_dict_number(dict_T *d, char_u *key);
+char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
 int string2float(char_u *text, float_T *value);
 char_u *get_function_name(expand_T *xp, int idx);
 char_u *get_expr_name(expand_T *xp, int idx);
 int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict_in);
 buf_T *buflist_find_by_name(char_u *name, int curtab_only);
 int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv);
+void evalcmd_redir_str(char_u *value, int value_len);
 void dict_extend(dict_T *d1, dict_T *d2, char_u *action);
 void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
 float_T vim_round(float_T f);
@@ -150,5 +152,4 @@ void ex_oldfiles(exarg_T *eap);
 void reset_v_option_vars(void);
 int modify_fname(char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen);
 char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags);
-char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
 /* vim: set ft=c : */
index e7f48bcfd3147992168298d53d8e54116a3429b1..a9bda875f9f5162066a659f1d15ca9bf1607d5ae 100644 (file)
@@ -1,8 +1,33 @@
 " test evalcmd()
 
+func NestedEval()
+  let nested = evalcmd('echo "nested\nlines"')
+  echo 'got: "' . nested . '"'
+endfunc
+
+func NestedRedir()
+  redir => var
+  echo 'broken'
+  redir END
+endfunc
+
 func Test_evalcmd()
   call assert_equal("\nnocompatible", evalcmd('set compatible?'))
   call assert_equal("\nsomething\nnice", evalcmd('echo "something\nnice"'))
+  call assert_equal("noendofline", evalcmd('echon "noendofline"'))
+  call assert_equal("", evalcmd(123))
+
+  call assert_equal("\ngot: \"\nnested\nlines\"", evalcmd('call NestedEval()'))
+  redir => redired
+  echo 'this'
+  let evaled = evalcmd('echo "that"')
+  echo 'theend'
+  redir END
+  call assert_equal("\nthis\ntheend", redired)
+  call assert_equal("\nthat", evaled)
+
   call assert_fails('call evalcmd("doesnotexist")', 'E492:')
+  call assert_fails('call evalcmd(3.4)', 'E806:')
+  call assert_fails('call evalcmd("call NestedRedir()")', 'E930:')
 endfunc
 
index 368d1b8be2f88e221a2b94ac227c356212c2edf8..5794e3a2fee6d5caf29d933c36138f612ae7f08f 100644 (file)
@@ -758,6 +758,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1999,
 /**/
     1998,
 /**/