To: vim_dev@googlegroups.com Subject: Patch 7.4.1999 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@Moolenaar.net -- 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 ///