To: vim_dev@googlegroups.com Subject: Patch 8.2.4679 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4679 Problem: Cannot have expandcmd() give an error message for mistakes. Solution: Add an optional argument to give errors. Fix memory leak when expanding files fails. (Yegappan Lakshmanan, closes #10071) Files: runtime/doc/builtin.txt, src/evalfunc.c, src/filepath.c, src/testdir/test_expand.vim, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.4678/runtime/doc/builtin.txt 2022-04-02 21:12:11.006733246 +0100 --- runtime/doc/builtin.txt 2022-04-03 21:24:27.558903210 +0100 *************** *** 161,167 **** exp({expr}) Float exponential of {expr} expand({expr} [, {nosuf} [, {list}]]) any expand special keywords in {expr} ! expandcmd({expr}) String expand {expr} like with `:edit` extend({expr1}, {expr2} [, {expr3}]) List/Dict insert items of {expr2} into {expr1} extendnew({expr1}, {expr2} [, {expr3}]) --- 161,168 ---- exp({expr}) Float exponential of {expr} expand({expr} [, {nosuf} [, {list}]]) any expand special keywords in {expr} ! expandcmd({string} [, {options}]) ! String expand {string} like with `:edit` extend({expr1}, {expr2} [, {expr3}]) List/Dict insert items of {expr2} into {expr1} extendnew({expr1}, {expr2} [, {expr3}]) *************** *** 2286,2303 **** Can also be used as a |method|: > Getpattern()->expand() ! expandcmd({string}) *expandcmd()* Expand special items in String {string} like what is done for an Ex command such as `:edit`. This expands special keywords, like with |expand()|, and environment variables, anywhere in {string}. "~user" and "~/path" are only expanded at the start. Returns the expanded string. If an error is encountered during expansion, the unmodified {string} is returned. Example: > :echo expandcmd('make %<.o') ! < make /path/runtime/doc/builtin.o ~ ! Can also be used as a |method|: > GetCommand()->expandcmd() < --- 2294,2320 ---- Can also be used as a |method|: > Getpattern()->expand() ! expandcmd({string} [, {options}]) *expandcmd()* Expand special items in String {string} like what is done for an Ex command such as `:edit`. This expands special keywords, like with |expand()|, and environment variables, anywhere in {string}. "~user" and "~/path" are only expanded at the start. + + The following items are supported in the {options} Dict + argument: + errmsg If set to TRUE, error messages are displayed + if an error is encountered during expansion. + By default, error messages are not displayed. + Returns the expanded string. If an error is encountered during expansion, the unmodified {string} is returned. + Example: > :echo expandcmd('make %<.o') ! make /path/runtime/doc/builtin.o ! :echo expandcmd('make %<.o', {'errmsg': v:true}) ! < Can also be used as a |method|: > GetCommand()->expandcmd() < *** ../vim-8.2.4678/src/evalfunc.c 2022-04-03 18:01:39.655574461 +0100 --- src/evalfunc.c 2022-04-03 21:24:27.558903210 +0100 *************** *** 1761,1767 **** ret_float, FLOAT_FUNC(f_exp)}, {"expand", 1, 3, FEARG_1, arg3_string_bool_bool, ret_any, f_expand}, ! {"expandcmd", 1, 1, FEARG_1, arg1_string, ret_string, f_expandcmd}, {"extend", 2, 3, FEARG_1, arg23_extend, ret_extend, f_extend}, --- 1761,1767 ---- ret_float, FLOAT_FUNC(f_exp)}, {"expand", 1, 3, FEARG_1, arg3_string_bool_bool, ret_any, f_expand}, ! {"expandcmd", 1, 2, FEARG_1, arg2_string_dict, ret_string, f_expandcmd}, {"extend", 2, 3, FEARG_1, arg23_extend, ret_extend, f_extend}, *************** *** 4152,4161 **** exarg_T eap; char_u *cmdstr; char *errormsg = NULL; ! if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) return; rettv->v_type = VAR_STRING; cmdstr = vim_strsave(tv_get_string(&argvars[0])); --- 4152,4169 ---- exarg_T eap; char_u *cmdstr; char *errormsg = NULL; + int emsgoff = TRUE; ! if (in_vim9script() ! && (check_for_string_arg(argvars, 0) == FAIL ! || check_for_opt_dict_arg(argvars, 1) == FAIL)) return; + if (argvars[1].v_type == VAR_DICT + && dict_get_bool(argvars[1].vval.v_dict, (char_u *)"errmsg", + VVAL_FALSE)) + emsgoff = FALSE; + rettv->v_type = VAR_STRING; cmdstr = vim_strsave(tv_get_string(&argvars[0])); *************** *** 4167,4175 **** eap.nextcmd = NULL; eap.cmdidx = CMD_USER; ! ++emsg_off; ! expand_filename(&eap, &cmdstr, &errormsg); ! --emsg_off; rettv->vval.v_string = cmdstr; } --- 4175,4187 ---- eap.nextcmd = NULL; eap.cmdidx = CMD_USER; ! if (emsgoff) ! ++emsg_off; ! if (expand_filename(&eap, &cmdstr, &errormsg) == FAIL) ! if (!emsgoff && errormsg != NULL && *errormsg != NUL) ! emsg(errormsg); ! if (emsgoff) ! --emsg_off; rettv->vval.v_string = cmdstr; } *** ../vim-8.2.4678/src/filepath.c 2022-04-03 11:58:28.014196270 +0100 --- src/filepath.c 2022-04-03 21:24:27.562903206 +0100 *************** *** 3999,4005 **** // When returning FAIL the array must be freed here. if (retval == FAIL) ! ga_clear(&ga); *num_file = ga.ga_len; *file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data --- 3999,4005 ---- // When returning FAIL the array must be freed here. if (retval == FAIL) ! ga_clear_strings(&ga); *num_file = ga.ga_len; *file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data *** ../vim-8.2.4678/src/testdir/test_expand.vim 2022-04-02 21:12:11.006733246 +0100 --- src/testdir/test_expand.vim 2022-04-03 21:24:27.562903206 +0100 *************** *** 90,103 **** " Test for expression expansion `= let $FOO= "blue" call assert_equal("blue sky", expandcmd("`=$FOO .. ' sky'`")) " Test for env variable with spaces let $FOO= "foo bar baz" call assert_equal("e foo bar baz", expandcmd("e $FOO")) ! if has('unix') ! " test for using the shell to expand a command argument ! call assert_equal('{1..4}', expandcmd('{1..4}')) endif unlet $FOO --- 90,115 ---- " Test for expression expansion `= let $FOO= "blue" call assert_equal("blue sky", expandcmd("`=$FOO .. ' sky'`")) + let x = expandcmd("`=axbycz`") + call assert_equal('`=axbycz`', x) + call assert_fails('let x = expandcmd("`=axbycz`", #{errmsg: 1})', 'E121:') + let x = expandcmd("`=axbycz`", #{abc: []}) + call assert_equal('`=axbycz`', x) " Test for env variable with spaces let $FOO= "foo bar baz" call assert_equal("e foo bar baz", expandcmd("e $FOO")) ! if has('unix') && executable('bash') ! " test for using the shell to expand a command argument. ! " only bash supports the {..} syntax ! set shell=bash ! let x = expandcmd('{1..4}') ! call assert_equal('{1..4}', x) ! call assert_fails("let x = expandcmd('{1..4}', #{errmsg: v:true})", 'E77:') ! let x = expandcmd('{1..4}', #{error: v:true}) ! call assert_equal('{1..4}', x) ! set shell& endif unlet $FOO *** ../vim-8.2.4678/src/testdir/test_vim9_builtin.vim 2022-03-28 18:16:43.619673423 +0100 --- src/testdir/test_vim9_builtin.vim 2022-04-03 21:24:27.562903206 +0100 *************** *** 1020,1025 **** --- 1020,1026 ---- expandcmd('')->assert_equal('') v9.CheckDefAndScriptFailure(['expandcmd([1])'], ['E1013: Argument 1: type mismatch, expected string but got list', 'E1174: String required for argument 1']) + v9.CheckDefAndScriptFailure(['expandcmd("abc", [])'], ['E1013: Argument 2: type mismatch, expected dict but got list', 'E1206: Dictionary required for argument 2']) enddef def Test_extend_arg_types() *** ../vim-8.2.4678/src/version.c 2022-04-03 21:11:31.031579240 +0100 --- src/version.c 2022-04-03 21:28:42.422658920 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4679, /**/ -- Q: Why does /dev/null accept only integers? A: You can't sink a float. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///