Patch 7.4.1999
Problem: evalcmd() doesn't work recursively.
Solution: Use redir_evalcmd instead of redir_vname.
Files: src/message.c, src/eval.c, src/globals.h, src/proto/eval.pro,
src/testdir/test_evalcmd.vim
*** ../vim-7.4.1998/src/message.c 2016-07-01 18:16:47.493936250 +0200
--- src/message.c 2016-07-07 22:52:52.899361546 +0200
***************
*** 3063,3069 ****
while (cur_col < msg_col)
{
#ifdef FEAT_EVAL
! if (redir_reg)
write_reg_contents(redir_reg, (char_u *)" ", -1, TRUE);
else if (redir_vname)
var_redir_str((char_u *)" ", -1);
--- 3063,3071 ----
while (cur_col < msg_col)
{
#ifdef FEAT_EVAL
! 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,3086 ****
}
#ifdef FEAT_EVAL
! if (redir_reg)
write_reg_contents(redir_reg, s, maxlen, TRUE);
! if (redir_vname)
var_redir_str(s, maxlen);
#endif
--- 3080,3090 ----
}
#ifdef FEAT_EVAL
! if (redir_evalcmd)
! evalcmd_redir_str(s, maxlen);
! else if (redir_reg)
write_reg_contents(redir_reg, s, maxlen, TRUE);
! else if (redir_vname)
var_redir_str(s, maxlen);
#endif
***************
*** 3088,3094 ****
while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
{
#ifdef FEAT_EVAL
! if (!redir_reg && !redir_vname)
#endif
if (redir_fd != NULL)
putc(*s, redir_fd);
--- 3092,3098 ----
while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
{
#ifdef FEAT_EVAL
! if (!redir_reg && !redir_vname && !redir_evalcmd)
#endif
if (redir_fd != NULL)
putc(*s, redir_fd);
***************
*** 3113,3119 ****
{
return redir_fd != NULL || *p_vfile != NUL
#ifdef FEAT_EVAL
! || redir_reg || redir_vname
#endif
;
}
--- 3117,3123 ----
{
return redir_fd != NULL || *p_vfile != NUL
#ifdef FEAT_EVAL
! || redir_reg || redir_vname || redir_evalcmd
#endif
;
}
*** ../vim-7.4.1998/src/eval.c 2016-07-07 17:32:48.286238524 +0200
--- src/eval.c 2016-07-07 22:36:11.245965220 +0200
***************
*** 11345,11350 ****
--- 11345,11372 ----
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,11357 ****
--- 11374,11382 ----
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,11378 ****
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 (do_cmdline_cmd(s) == OK)
! rettv->vval.v_string = redir_ga.ga_data;
! else
! vim_free(redir_ga.ga_data);
!
! redir_ga.ga_data = NULL;
! redir_vname = FALSE;
! redir_lval = NULL;
}
-
}
/*
--- 11384,11403 ----
s = get_tv_string_chk(&argvars[0]);
if (s != NULL)
{
! if (redir_evalcmd)
! save_ga = redir_evalcmd_ga;
! ga_init2(&redir_evalcmd_ga, (int)sizeof(char), 500);
! redir_evalcmd = TRUE;
!
! ++msg_silent;
! do_cmdline_cmd(s);
! rettv->vval.v_string = redir_evalcmd_ga.ga_data;
! msg_silent = save_msg_silent;
!
! redir_evalcmd = save_redir_evalcmd;
! if (redir_evalcmd)
! redir_evalcmd_ga = save_ga;
}
}
/*
*** ../vim-7.4.1998/src/globals.h 2016-06-26 16:44:19.515620934 +0200
--- src/globals.h 2016-07-07 22:18:55.529092396 +0200
***************
*** 1106,1111 ****
--- 1106,1112 ----
#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
*** ../vim-7.4.1998/src/proto/eval.pro 2016-07-01 18:16:47.497936191 +0200
--- src/proto/eval.pro 2016-07-07 22:24:54.823852447 +0200
***************
*** 81,92 ****
--- 81,94 ----
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,154 ****
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 : */
--- 152,155 ----
*** ../vim-7.4.1998/src/testdir/test_evalcmd.vim 2016-07-07
17:32:48.290238465 +0200
--- src/testdir/test_evalcmd.vim 2016-07-07 23:01:05.328236260 +0200
***************
*** 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
*** ../vim-7.4.1998/src/version.c 2016-07-07 20:45:00.740424639 +0200
--- src/version.c 2016-07-07 22:42:27.568453291 +0200
***************
*** 760,761 ****
--- 760,763 ----
{ /* Add new patch number below this line */
+ /**/
+ 1999,
/**/
--
hundred-and-one symptoms of being an internet addict:
224. You set up your own Web page. You set up a Web page for each
of your kids... and your pets.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.