Patch 7.4.1875
Problem:    Comparing functions and partials doesn't work well.
Solution:   Add tests. (Nikolai Pavlov)  Compare the dict and arguments in the
            partial. (closes #813)
Files:      src/eval.c, src/testdir/test_partial.vim


*** ../vim-7.4.1874/src/eval.c  2016-06-01 23:08:35.249421504 +0200
--- src/eval.c  2016-06-02 17:37:10.884506528 +0200
***************
*** 4627,4633 ****
                    clear_tv(&var2);
                    return FAIL;
                }
!               n1 = tv_equal(rettv, &var2, FALSE, FALSE);
                if (type == TYPE_NEQUAL)
                    n1 = !n1;
            }
--- 4627,4652 ----
                    clear_tv(&var2);
                    return FAIL;
                }
!               if ((rettv->v_type == VAR_PARTIAL
!                                            && rettv->vval.v_partial == NULL)
!                       || (var2.v_type == VAR_PARTIAL
!                                             && var2.vval.v_partial == NULL))
!                   /* when a partial is NULL assume not equal */
!                   n1 = FALSE;
!               else if (type_is)
!               {
!                   if (rettv->v_type == VAR_FUNC && var2.v_type == VAR_FUNC)
!                       /* strings are considered the same if their value is
!                        * the same */
!                       n1 = tv_equal(rettv, &var2, ic, FALSE);
!                   else if (rettv->v_type == VAR_PARTIAL
!                                               && var2.v_type == VAR_PARTIAL)
!                       n1 = (rettv->vval.v_partial == var2.vval.v_partial);
!                   else
!                       n1 = FALSE;
!               }
!               else
!                   n1 = tv_equal(rettv, &var2, ic, FALSE);
                if (type == TYPE_NEQUAL)
                    n1 = !n1;
            }
***************
*** 6258,6263 ****
--- 6277,6334 ----
  
  static int tv_equal_recurse_limit;
  
+     static int
+ func_equal(
+     typval_T *tv1,
+     typval_T *tv2,
+     int            ic)            /* ignore case */
+ {
+     char_u    *s1, *s2;
+     dict_T    *d1, *d2;
+     int               a1, a2;
+     int               i;
+ 
+     /* empty and NULL function name considered the same */
+     s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
+                                          : tv1->vval.v_partial->pt_name;
+     if (s1 != NULL && *s1 == NUL)
+       s1 = NULL;
+     s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
+                                          : tv2->vval.v_partial->pt_name;
+     if (s2 != NULL && *s2 == NUL)
+       s2 = NULL;
+     if (s1 == NULL || s2 == NULL)
+     {
+       if (s1 != s2)
+           return FALSE;
+     }
+     else if (STRCMP(s1, s2) != 0)
+       return FALSE;
+ 
+     /* empty dict and NULL dict is different */
+     d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict;
+     d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict;
+     if (d1 == NULL || d2 == NULL)
+     {
+       if (d1 != d2)
+           return FALSE;
+     }
+     else if (!dict_equal(d1, d2, ic, TRUE))
+       return FALSE;
+ 
+     /* empty list and no list considered the same */
+     a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc;
+     a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc;
+     if (a1 != a2)
+       return FALSE;
+     for (i = 0; i < a1; ++i)
+       if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
+                     tv2->vval.v_partial->pt_argv + i, ic, TRUE))
+           return FALSE;
+ 
+     return TRUE;
+ }
+ 
  /*
   * Return TRUE if "tv1" and "tv2" have the same value.
   * Compares the items just like "==" would compare them, but strings and
***************
*** 6275,6296 ****
      static int  recursive_cnt = 0;        /* catch recursive loops */
      int               r;
  
-     /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */
-     if ((tv1->v_type == VAR_FUNC
-               || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
-           && (tv2->v_type == VAR_FUNC
-               || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
-     {
-       s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
-                                              : tv1->vval.v_partial->pt_name;
-       s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
-                                              : tv2->vval.v_partial->pt_name;
-       return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0);
-     }
- 
-     if (tv1->v_type != tv2->v_type)
-       return FALSE;
- 
      /* Catch lists and dicts that have an endless loop by limiting
       * recursiveness to a limit.  We guess they are equal then.
       * A fixed limit has the problem of still taking an awful long time.
--- 6346,6351 ----
***************
*** 6305,6310 ****
--- 6360,6380 ----
        return TRUE;
      }
  
+     /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */
+     if ((tv1->v_type == VAR_FUNC
+               || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL))
+           && (tv2->v_type == VAR_FUNC
+               || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL)))
+     {
+       ++recursive_cnt;
+       r = func_equal(tv1, tv2, ic);
+       --recursive_cnt;
+       return r;
+     }
+ 
+     if (tv1->v_type != tv2->v_type)
+       return FALSE;
+ 
      switch (tv1->v_type)
      {
        case VAR_LIST:
*** ../vim-7.4.1874/src/testdir/test_partial.vim        2016-05-28 
22:47:08.542193208 +0200
--- src/testdir/test_partial.vim        2016-06-02 17:43:06.292501639 +0200
***************
*** 316,318 ****
--- 316,381 ----
    call assert_equal([], get(Func, 'args'))
    call assert_true(empty( get(Func, 'dict')))
  endfunc
+ 
+ func Test_compare_partials()
+   let d1 = {}
+   let d2 = {}
+ 
+   function d1.f1() dict
+   endfunction
+ 
+   function d1.f2() dict
+   endfunction
+ 
+   let F1 = get(d1, 'f1')
+   let F2 = get(d1, 'f2')
+ 
+   let F1d1 = function(F1, d1)
+   let F2d1 = function(F2, d2)
+   let F1d1a1 = function(F1d1, [1])
+   let F1d1a12 = function(F1d1, [1, 2])
+   let F1a1 = function(F1, [1])
+   let F1a2 = function(F1, [2])
+   let F1d2 = function(F1, d2)
+   let d3 = {'f1': F1, 'f2': F2}
+   let F1d3 = function(F1, d3)
+   let F1ad1 = function(F1, [d1])
+   let F1ad3 = function(F1, [d3])
+ 
+   call assert_match('^function(''\d\+'')$', string(F1))  " Not a partial
+   call assert_match('^function(''\d\+'')$', string(F2))  " Not a partial
+   call assert_match('^function(''\d\+'', {.*})$', string(F1d1))  " A partial
+   call assert_match('^function(''\d\+'', {.*})$', string(F2d1))  " A partial
+   call assert_match('^function(''\d\+'', \[.*\])$', string(F1a1))  " No dict
+ 
+   " !=
+   let X = F1
+   call assert_false(F1 != X)  " same function
+   let X = F1d1
+   call assert_false(F1d1 != X)  " same partial
+   let X = F1d1a1
+   call assert_false(F1d1a1 != X)  " same partial
+   let X = F1a1
+   call assert_false(F1a1 != X)  " same partial
+ 
+   call assert_true(F1 != F2)  " Different functions
+   call assert_true(F1 != F1d1)  " Partial /= non-partial
+   call assert_true(F1d1a1 != F1d1a12)  " Different number of arguments
+   call assert_true(F1a1 != F1d1a12)  " One has no dict
+   call assert_true(F1a1 != F1a2)  " Different arguments
+   call assert_true(F1d2 != F1d1)  " Different dictionaries
+   call assert_false(F1d1 != F1d3)  " Equal dictionaries, even though d1 isnot 
d3
+ 
+   " isnot, option 1
+   call assert_true(F1 isnot# F2)  " Different functions
+   call assert_true(F1 isnot# F1d1)  " Partial /= non-partial
+   call assert_true(F1d1 isnot# F1d3)  " d1 isnot d3, even though d1 == d3
+   call assert_true(F1a1 isnot# F1d1a12)  " One has no dict
+   call assert_true(F1a1 isnot# F1a2)  " Different number of arguments
+   call assert_true(F1ad1 isnot# F1ad3)  " In arguments d1 isnot d3
+ 
+   " isnot, option 2
+   call assert_true(F1 isnot# F2)  " Different functions
+   call assert_true(F1 isnot# F1d1)  " Partial /= non-partial
+   call assert_true(d1.f1 isnot# d1.f1)  " handle_subscript creates new 
partial each time
+ endfunc
*** ../vim-7.4.1874/src/version.c       2016-06-02 15:49:33.008595362 +0200
--- src/version.c       2016-06-02 17:41:19.840503104 +0200
***************
*** 755,756 ****
--- 755,758 ----
  {   /* Add new patch number below this line */
+ /**/
+     1875,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
38. You wake up at 3 a.m. to go to the bathroom and stop and check your e-mail
    on the way back to bed.

 /// 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.

Raspunde prin e-mail lui