]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 7.4.1644 v7.4.1644
authorBram Moolenaar <Bram@vim.org>
Thu, 24 Mar 2016 20:23:06 +0000 (21:23 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 24 Mar 2016 20:23:06 +0000 (21:23 +0100)
Problem:    Using string() on a partial that exists in the dictionary it binds
            results in an error. (Nikolai Pavlov)
Solution:   Make string() not fail on a recursively nested structure. (Ken
            Takta)

src/eval.c
src/testdir/test_partial.vim
src/version.c

index 55d61e79bdd03a39c7bee3f3414c95e7930d0612..453756217715052fe339af93fe6c6c95237b89f8 100644 (file)
@@ -7851,10 +7851,50 @@ echo_string(
            break;
 
        case VAR_PARTIAL:
-           *tofree = NULL;
-           /* TODO: arguments */
-           r = tv->vval.v_partial == NULL ? NULL : tv->vval.v_partial->pt_name;
-           break;
+           {
+               partial_T   *pt = tv->vval.v_partial;
+               char_u      *fname = string_quote(pt == NULL ? NULL
+                                                       : pt->pt_name, FALSE);
+               garray_T    ga;
+               int         i;
+               char_u      *tf;
+
+               ga_init2(&ga, 1, 100);
+               ga_concat(&ga, (char_u *)"function(");
+               if (fname != NULL)
+               {
+                   ga_concat(&ga, fname);
+                   vim_free(fname);
+               }
+               if (pt != NULL && pt->pt_argc > 0)
+               {
+                   ga_concat(&ga, (char_u *)", [");
+                   for (i = 0; i < pt->pt_argc; ++i)
+                   {
+                       if (i > 0)
+                           ga_concat(&ga, (char_u *)", ");
+                       ga_concat(&ga,
+                            tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
+                       vim_free(tf);
+                   }
+                   ga_concat(&ga, (char_u *)"]");
+               }
+               if (pt != NULL && pt->pt_dict != NULL)
+               {
+                   typval_T dtv;
+
+                   ga_concat(&ga, (char_u *)", ");
+                   dtv.v_type = VAR_DICT;
+                   dtv.vval.v_dict = pt->pt_dict;
+                   ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
+                   vim_free(tf);
+               }
+               ga_concat(&ga, (char_u *)")");
+
+               *tofree = ga.ga_data;
+               r = *tofree;
+               break;
+           }
 
        case VAR_LIST:
            if (tv->vval.v_list == NULL)
@@ -7941,50 +7981,6 @@ tv2string(
        case VAR_FUNC:
            *tofree = string_quote(tv->vval.v_string, TRUE);
            return *tofree;
-       case VAR_PARTIAL:
-           {
-               partial_T   *pt = tv->vval.v_partial;
-               char_u      *fname = string_quote(pt == NULL ? NULL
-                                                       : pt->pt_name, FALSE);
-               garray_T    ga;
-               int         i;
-               char_u      *tf;
-
-               ga_init2(&ga, 1, 100);
-               ga_concat(&ga, (char_u *)"function(");
-               if (fname != NULL)
-               {
-                   ga_concat(&ga, fname);
-                   vim_free(fname);
-               }
-               if (pt != NULL && pt->pt_argc > 0)
-               {
-                   ga_concat(&ga, (char_u *)", [");
-                   for (i = 0; i < pt->pt_argc; ++i)
-                   {
-                       if (i > 0)
-                           ga_concat(&ga, (char_u *)", ");
-                       ga_concat(&ga,
-                            tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
-                       vim_free(tf);
-                   }
-                   ga_concat(&ga, (char_u *)"]");
-               }
-               if (pt != NULL && pt->pt_dict != NULL)
-               {
-                   typval_T dtv;
-
-                   ga_concat(&ga, (char_u *)", ");
-                   dtv.v_type = VAR_DICT;
-                   dtv.vval.v_dict = pt->pt_dict;
-                   ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));
-                   vim_free(tf);
-               }
-               ga_concat(&ga, (char_u *)")");
-
-               *tofree = ga.ga_data;
-               return *tofree;
-           }
        case VAR_STRING:
            *tofree = string_quote(tv->vval.v_string, FALSE);
            return *tofree;
@@ -7997,6 +7993,7 @@ tv2string(
        case VAR_NUMBER:
        case VAR_LIST:
        case VAR_DICT:
+       case VAR_PARTIAL:
        case VAR_SPECIAL:
        case VAR_JOB:
        case VAR_CHANNEL:
@@ -19258,7 +19255,8 @@ f_string(typval_T *argvars, typval_T *rettv)
     char_u     numbuf[NUMBUFLEN];
 
     rettv->v_type = VAR_STRING;
-    rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
+    rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf,
+                                                               get_copyID());
     /* Make a copy if we have a value but it's not in allocated memory. */
     if (rettv->vval.v_string != NULL && tofree == NULL)
        rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
index f67bb41dd8a74bc7cdb8fe6082529ff701058839..75cc492515f4c07887ea9829f93d63ada8975bd1 100644 (file)
@@ -180,3 +180,16 @@ func Test_func_unref()
   unlet obj
   call assert_false(exists('*{' . funcnumber . '}'))
 endfunc
+
+func Test_tostring()
+  let d = {}
+  let d.d = d
+  function d.test3()
+    echo 42
+  endfunction
+  try
+    call string(d.test3)
+  catch
+    call assert_true(v:false, v:exception)
+  endtry
+endfunc
index 4cd93d2844a53411b8121817e242f8d34e50f860..b90a0d0a99f0c718410783914b996ad963f66f4e 100644 (file)
@@ -748,6 +748,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1644,
 /**/
     1643,
 /**/