changeset 8548:24db3583c496 v7.4.1564

commit https://github.com/vim/vim/commit/346418c624f1bc7c04c98907134a2b284e6452dd Author: Bram Moolenaar <Bram@vim.org> Date: Tue Mar 15 12:36:08 2016 +0100 patch 7.4.1564 Problem: An empty list in function() causes an error. Solution: Handle an empty list like there is no list of arguments.
author Christian Brabandt <cb@256bit.org>
date Tue, 15 Mar 2016 12:45:05 +0100
parents b9d478c99f98
children 1b47edf4545a
files src/eval.c src/testdir/test_partial.vim src/version.c
diffstat 3 files changed, 44 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -11786,6 +11786,10 @@ f_function(typval_T *argvars, typval_T *
 	EMSG2(_("E700: Unknown function: %s"), s);
     else
     {
+	int	dict_idx = 0;
+	int	arg_idx = 0;
+	list_T	*list = NULL;
+
 	if (STRNCMP(s, "s:", 2) == 0 || STRNCMP(s, "<SID>", 5) == 0)
 	{
 	    char	sid_buf[25];
@@ -11808,10 +11812,6 @@ f_function(typval_T *argvars, typval_T *
 
 	if (argvars[1].v_type != VAR_UNKNOWN)
 	{
-	    partial_T	*pt;
-	    int		dict_idx = 0;
-	    int		arg_idx = 0;
-
 	    if (argvars[2].v_type != VAR_UNKNOWN)
 	    {
 		/* function(name, [args], dict) */
@@ -11824,27 +11824,38 @@ f_function(typval_T *argvars, typval_T *
 	    else
 		/* function(name, [args]) */
 		arg_idx = 1;
-	    if (dict_idx > 0 && (argvars[dict_idx].v_type != VAR_DICT
-				     || argvars[dict_idx].vval.v_dict == NULL))
-	    {
-		EMSG(_("E922: expected a dict"));
-		vim_free(name);
-		return;
-	    }
-	    if (arg_idx > 0 && (argvars[arg_idx].v_type != VAR_LIST
-				     || argvars[arg_idx].vval.v_list == NULL))
-	    {
-		EMSG(_("E923: Second argument of function() must be a list or a dict"));
-		vim_free(name);
-		return;
-	    }
-
-	    pt = (partial_T *)alloc_clear(sizeof(partial_T));
+	    if (dict_idx > 0)
+	    {
+		if (argvars[dict_idx].v_type != VAR_DICT)
+		{
+		    EMSG(_("E922: expected a dict"));
+		    vim_free(name);
+		    return;
+		}
+		if (argvars[dict_idx].vval.v_dict == NULL)
+		    dict_idx = 0;
+	    }
+	    if (arg_idx > 0)
+	    {
+		if (argvars[arg_idx].v_type != VAR_LIST)
+		{
+		    EMSG(_("E923: Second argument of function() must be a list or a dict"));
+		    vim_free(name);
+		    return;
+		}
+		list = argvars[arg_idx].vval.v_list;
+		if (list == NULL || list->lv_len == 0)
+		    arg_idx = 0;
+	    }
+	}
+	if (dict_idx > 0 || arg_idx > 0)
+	{
+	    partial_T	*pt = (partial_T *)alloc_clear(sizeof(partial_T));
+
 	    if (pt != NULL)
 	    {
 		if (arg_idx > 0)
 		{
-		    list_T	*list = argvars[arg_idx].vval.v_list;
 		    listitem_T	*li;
 		    int		i = 0;
 
--- a/src/testdir/test_partial.vim
+++ b/src/testdir/test_partial.vim
@@ -19,6 +19,9 @@ func Test_partial_args()
   call assert_equal("foo/bar/xxx", Cb("xxx"))
   call assert_equal("foo/bar/yyy", call(Cb, ["yyy"]))
 
+  let Cb = function('MyFunc', [])
+  call assert_equal("a/b/c", Cb("a", "b", "c"))
+
   let Sort = function('MySort', [1])
   call assert_equal([1, 2, 3], sort([3, 1, 2], Sort))
   let Sort = function('MySort', [0])
@@ -34,10 +37,16 @@ func Test_partial_dict()
   let Cb = function('MyDictFunc', ["foo", "bar"], dict)
   call assert_equal("hello/foo/bar", Cb())
   call assert_fails('Cb("xxx")', 'E492:')
+
   let Cb = function('MyDictFunc', ["foo"], dict)
   call assert_equal("hello/foo/xxx", Cb("xxx"))
   call assert_fails('Cb()', 'E492:')
+
+  let Cb = function('MyDictFunc', [], dict)
+  call assert_equal("hello/ttt/xxx", Cb("ttt", "xxx"))
+  call assert_fails('Cb("yyy")', 'E492:')
+
   let Cb = function('MyDictFunc', dict)
   call assert_equal("hello/xxx/yyy", Cb("xxx", "yyy"))
-  call assert_fails('Cb()', 'E492:')
+  call assert_fails('Cb("fff")', 'E492:')
 endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -744,6 +744,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1564,
+/**/
     1563,
 /**/
     1562,