|
Karsten Hopp |
634b72 |
To: vim_dev@googlegroups.com
|
|
Karsten Hopp |
634b72 |
Subject: Patch 7.3.055
|
|
Karsten Hopp |
634b72 |
Fcc: outbox
|
|
Karsten Hopp |
634b72 |
From: Bram Moolenaar <Bram@moolenaar.net>
|
|
Karsten Hopp |
634b72 |
Mime-Version: 1.0
|
|
Karsten Hopp |
634b72 |
Content-Type: text/plain; charset=UTF-8
|
|
Karsten Hopp |
634b72 |
Content-Transfer-Encoding: 8bit
|
|
Karsten Hopp |
634b72 |
------------
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
Patch 7.3.055
|
|
Karsten Hopp |
634b72 |
Problem: Recursively nested lists and dictionaries cause a near-endless
|
|
Karsten Hopp |
634b72 |
loop when comparing them with a copy. (ZyX)
|
|
Karsten Hopp |
634b72 |
Solution: Limit recursiveness in a way that non-recursive structures can
|
|
Karsten Hopp |
634b72 |
still be nested very deep.
|
|
Karsten Hopp |
634b72 |
Files: src/eval.c, src/testdir/test55.in, src/testdir/test55.ok
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
*** ../vim-7.3.054/src/eval.c 2010-10-20 21:22:17.000000000 +0200
|
|
Karsten Hopp |
634b72 |
--- src/eval.c 2010-11-10 20:02:57.000000000 +0100
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 434,442 ****
|
|
Karsten Hopp |
634b72 |
static void listitem_free __ARGS((listitem_T *item));
|
|
Karsten Hopp |
634b72 |
static void listitem_remove __ARGS((list_T *l, listitem_T *item));
|
|
Karsten Hopp |
634b72 |
static long list_len __ARGS((list_T *l));
|
|
Karsten Hopp |
634b72 |
! static int list_equal __ARGS((list_T *l1, list_T *l2, int ic));
|
|
Karsten Hopp |
634b72 |
! static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic));
|
|
Karsten Hopp |
634b72 |
! static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic));
|
|
Karsten Hopp |
634b72 |
static listitem_T *list_find __ARGS((list_T *l, long n));
|
|
Karsten Hopp |
634b72 |
static long list_find_nr __ARGS((list_T *l, long idx, int *errorp));
|
|
Karsten Hopp |
634b72 |
static long list_idx_of_item __ARGS((list_T *l, listitem_T *item));
|
|
Karsten Hopp |
634b72 |
--- 434,442 ----
|
|
Karsten Hopp |
634b72 |
static void listitem_free __ARGS((listitem_T *item));
|
|
Karsten Hopp |
634b72 |
static void listitem_remove __ARGS((list_T *l, listitem_T *item));
|
|
Karsten Hopp |
634b72 |
static long list_len __ARGS((list_T *l));
|
|
Karsten Hopp |
634b72 |
! static int list_equal __ARGS((list_T *l1, list_T *l2, int ic, int recursive));
|
|
Karsten Hopp |
634b72 |
! static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic, int recursive));
|
|
Karsten Hopp |
634b72 |
! static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic, int recursive));
|
|
Karsten Hopp |
634b72 |
static listitem_T *list_find __ARGS((list_T *l, long n));
|
|
Karsten Hopp |
634b72 |
static long list_find_nr __ARGS((list_T *l, long idx, int *errorp));
|
|
Karsten Hopp |
634b72 |
static long list_idx_of_item __ARGS((list_T *l, listitem_T *item));
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 4350,4356 ****
|
|
Karsten Hopp |
634b72 |
else
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
/* Compare two Lists for being equal or unequal. */
|
|
Karsten Hopp |
634b72 |
! n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic);
|
|
Karsten Hopp |
634b72 |
if (type == TYPE_NEQUAL)
|
|
Karsten Hopp |
634b72 |
n1 = !n1;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
--- 4350,4357 ----
|
|
Karsten Hopp |
634b72 |
else
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
/* Compare two Lists for being equal or unequal. */
|
|
Karsten Hopp |
634b72 |
! n1 = list_equal(rettv->vval.v_list, var2.vval.v_list,
|
|
Karsten Hopp |
634b72 |
! ic, FALSE);
|
|
Karsten Hopp |
634b72 |
if (type == TYPE_NEQUAL)
|
|
Karsten Hopp |
634b72 |
n1 = !n1;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 4379,4385 ****
|
|
Karsten Hopp |
634b72 |
else
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
/* Compare two Dictionaries for being equal or unequal. */
|
|
Karsten Hopp |
634b72 |
! n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic);
|
|
Karsten Hopp |
634b72 |
if (type == TYPE_NEQUAL)
|
|
Karsten Hopp |
634b72 |
n1 = !n1;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
--- 4380,4387 ----
|
|
Karsten Hopp |
634b72 |
else
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
/* Compare two Dictionaries for being equal or unequal. */
|
|
Karsten Hopp |
634b72 |
! n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict,
|
|
Karsten Hopp |
634b72 |
! ic, FALSE);
|
|
Karsten Hopp |
634b72 |
if (type == TYPE_NEQUAL)
|
|
Karsten Hopp |
634b72 |
n1 = !n1;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 5914,5923 ****
|
|
Karsten Hopp |
634b72 |
* Return TRUE when two lists have exactly the same values.
|
|
Karsten Hopp |
634b72 |
*/
|
|
Karsten Hopp |
634b72 |
static int
|
|
Karsten Hopp |
634b72 |
! list_equal(l1, l2, ic)
|
|
Karsten Hopp |
634b72 |
list_T *l1;
|
|
Karsten Hopp |
634b72 |
list_T *l2;
|
|
Karsten Hopp |
634b72 |
int ic; /* ignore case for strings */
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
listitem_T *item1, *item2;
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
--- 5916,5926 ----
|
|
Karsten Hopp |
634b72 |
* Return TRUE when two lists have exactly the same values.
|
|
Karsten Hopp |
634b72 |
*/
|
|
Karsten Hopp |
634b72 |
static int
|
|
Karsten Hopp |
634b72 |
! list_equal(l1, l2, ic, recursive)
|
|
Karsten Hopp |
634b72 |
list_T *l1;
|
|
Karsten Hopp |
634b72 |
list_T *l2;
|
|
Karsten Hopp |
634b72 |
int ic; /* ignore case for strings */
|
|
Karsten Hopp |
634b72 |
+ int recursive; /* TRUE when used recursively */
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
listitem_T *item1, *item2;
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 5931,5937 ****
|
|
Karsten Hopp |
634b72 |
for (item1 = l1->lv_first, item2 = l2->lv_first;
|
|
Karsten Hopp |
634b72 |
item1 != NULL && item2 != NULL;
|
|
Karsten Hopp |
634b72 |
item1 = item1->li_next, item2 = item2->li_next)
|
|
Karsten Hopp |
634b72 |
! if (!tv_equal(&item1->li_tv, &item2->li_tv, ic))
|
|
Karsten Hopp |
634b72 |
return FALSE;
|
|
Karsten Hopp |
634b72 |
return item1 == NULL && item2 == NULL;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
--- 5934,5940 ----
|
|
Karsten Hopp |
634b72 |
for (item1 = l1->lv_first, item2 = l2->lv_first;
|
|
Karsten Hopp |
634b72 |
item1 != NULL && item2 != NULL;
|
|
Karsten Hopp |
634b72 |
item1 = item1->li_next, item2 = item2->li_next)
|
|
Karsten Hopp |
634b72 |
! if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive))
|
|
Karsten Hopp |
634b72 |
return FALSE;
|
|
Karsten Hopp |
634b72 |
return item1 == NULL && item2 == NULL;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 5953,5962 ****
|
|
Karsten Hopp |
634b72 |
* Return TRUE when two dictionaries have exactly the same key/values.
|
|
Karsten Hopp |
634b72 |
*/
|
|
Karsten Hopp |
634b72 |
static int
|
|
Karsten Hopp |
634b72 |
! dict_equal(d1, d2, ic)
|
|
Karsten Hopp |
634b72 |
dict_T *d1;
|
|
Karsten Hopp |
634b72 |
dict_T *d2;
|
|
Karsten Hopp |
634b72 |
int ic; /* ignore case for strings */
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
hashitem_T *hi;
|
|
Karsten Hopp |
634b72 |
dictitem_T *item2;
|
|
Karsten Hopp |
634b72 |
--- 5956,5966 ----
|
|
Karsten Hopp |
634b72 |
* Return TRUE when two dictionaries have exactly the same key/values.
|
|
Karsten Hopp |
634b72 |
*/
|
|
Karsten Hopp |
634b72 |
static int
|
|
Karsten Hopp |
634b72 |
! dict_equal(d1, d2, ic, recursive)
|
|
Karsten Hopp |
634b72 |
dict_T *d1;
|
|
Karsten Hopp |
634b72 |
dict_T *d2;
|
|
Karsten Hopp |
634b72 |
int ic; /* ignore case for strings */
|
|
Karsten Hopp |
634b72 |
+ int recursive; /* TRUE when used recursively */
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
hashitem_T *hi;
|
|
Karsten Hopp |
634b72 |
dictitem_T *item2;
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 5977,5983 ****
|
|
Karsten Hopp |
634b72 |
item2 = dict_find(d2, hi->hi_key, -1);
|
|
Karsten Hopp |
634b72 |
if (item2 == NULL)
|
|
Karsten Hopp |
634b72 |
return FALSE;
|
|
Karsten Hopp |
634b72 |
! if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic))
|
|
Karsten Hopp |
634b72 |
return FALSE;
|
|
Karsten Hopp |
634b72 |
--todo;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
--- 5981,5987 ----
|
|
Karsten Hopp |
634b72 |
item2 = dict_find(d2, hi->hi_key, -1);
|
|
Karsten Hopp |
634b72 |
if (item2 == NULL)
|
|
Karsten Hopp |
634b72 |
return FALSE;
|
|
Karsten Hopp |
634b72 |
! if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive))
|
|
Karsten Hopp |
634b72 |
return FALSE;
|
|
Karsten Hopp |
634b72 |
--todo;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 5985,6025 ****
|
|
Karsten Hopp |
634b72 |
return TRUE;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
/*
|
|
Karsten Hopp |
634b72 |
* Return TRUE if "tv1" and "tv2" have the same value.
|
|
Karsten Hopp |
634b72 |
* Compares the items just like "==" would compare them, but strings and
|
|
Karsten Hopp |
634b72 |
* numbers are different. Floats and numbers are also different.
|
|
Karsten Hopp |
634b72 |
*/
|
|
Karsten Hopp |
634b72 |
static int
|
|
Karsten Hopp |
634b72 |
! tv_equal(tv1, tv2, ic)
|
|
Karsten Hopp |
634b72 |
typval_T *tv1;
|
|
Karsten Hopp |
634b72 |
typval_T *tv2;
|
|
Karsten Hopp |
634b72 |
! int ic; /* ignore case */
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
|
|
Karsten Hopp |
634b72 |
char_u *s1, *s2;
|
|
Karsten Hopp |
634b72 |
! static int recursive = 0; /* cach recursive loops */
|
|
Karsten Hopp |
634b72 |
int r;
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
if (tv1->v_type != tv2->v_type)
|
|
Karsten Hopp |
634b72 |
return FALSE;
|
|
Karsten Hopp |
634b72 |
/* Catch lists and dicts that have an endless loop by limiting
|
|
Karsten Hopp |
634b72 |
! * recursiveness to 1000. We guess they are equal then. */
|
|
Karsten Hopp |
634b72 |
! if (recursive >= 1000)
|
|
Karsten Hopp |
634b72 |
return TRUE;
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
switch (tv1->v_type)
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
case VAR_LIST:
|
|
Karsten Hopp |
634b72 |
! ++recursive;
|
|
Karsten Hopp |
634b72 |
! r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic);
|
|
Karsten Hopp |
634b72 |
! --recursive;
|
|
Karsten Hopp |
634b72 |
return r;
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
case VAR_DICT:
|
|
Karsten Hopp |
634b72 |
! ++recursive;
|
|
Karsten Hopp |
634b72 |
! r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic);
|
|
Karsten Hopp |
634b72 |
! --recursive;
|
|
Karsten Hopp |
634b72 |
return r;
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
case VAR_FUNC:
|
|
Karsten Hopp |
634b72 |
--- 5989,6042 ----
|
|
Karsten Hopp |
634b72 |
return TRUE;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
+ static int tv_equal_recurse_limit;
|
|
Karsten Hopp |
634b72 |
+
|
|
Karsten Hopp |
634b72 |
/*
|
|
Karsten Hopp |
634b72 |
* Return TRUE if "tv1" and "tv2" have the same value.
|
|
Karsten Hopp |
634b72 |
* Compares the items just like "==" would compare them, but strings and
|
|
Karsten Hopp |
634b72 |
* numbers are different. Floats and numbers are also different.
|
|
Karsten Hopp |
634b72 |
*/
|
|
Karsten Hopp |
634b72 |
static int
|
|
Karsten Hopp |
634b72 |
! tv_equal(tv1, tv2, ic, recursive)
|
|
Karsten Hopp |
634b72 |
typval_T *tv1;
|
|
Karsten Hopp |
634b72 |
typval_T *tv2;
|
|
Karsten Hopp |
634b72 |
! int ic; /* ignore case */
|
|
Karsten Hopp |
634b72 |
! int recursive; /* TRUE when used recursively */
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
|
|
Karsten Hopp |
634b72 |
char_u *s1, *s2;
|
|
Karsten Hopp |
634b72 |
! static int recursive_cnt = 0; /* catch recursive loops */
|
|
Karsten Hopp |
634b72 |
int r;
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
if (tv1->v_type != tv2->v_type)
|
|
Karsten Hopp |
634b72 |
return FALSE;
|
|
Karsten Hopp |
634b72 |
+
|
|
Karsten Hopp |
634b72 |
/* Catch lists and dicts that have an endless loop by limiting
|
|
Karsten Hopp |
634b72 |
! * recursiveness to a limit. We guess they are equal then.
|
|
Karsten Hopp |
634b72 |
! * A fixed limit has the problem of still taking an awful long time.
|
|
Karsten Hopp |
634b72 |
! * Reduce the limit every time running into it. That should work fine for
|
|
Karsten Hopp |
634b72 |
! * deeply linked structures that are not recursively linked and catch
|
|
Karsten Hopp |
634b72 |
! * recursiveness quickly. */
|
|
Karsten Hopp |
634b72 |
! if (!recursive)
|
|
Karsten Hopp |
634b72 |
! tv_equal_recurse_limit = 1000;
|
|
Karsten Hopp |
634b72 |
! if (recursive_cnt >= tv_equal_recurse_limit)
|
|
Karsten Hopp |
634b72 |
! {
|
|
Karsten Hopp |
634b72 |
! --tv_equal_recurse_limit;
|
|
Karsten Hopp |
634b72 |
return TRUE;
|
|
Karsten Hopp |
634b72 |
+ }
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
switch (tv1->v_type)
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
case VAR_LIST:
|
|
Karsten Hopp |
634b72 |
! ++recursive_cnt;
|
|
Karsten Hopp |
634b72 |
! r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
|
|
Karsten Hopp |
634b72 |
! --recursive_cnt;
|
|
Karsten Hopp |
634b72 |
return r;
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
case VAR_DICT:
|
|
Karsten Hopp |
634b72 |
! ++recursive_cnt;
|
|
Karsten Hopp |
634b72 |
! r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
|
|
Karsten Hopp |
634b72 |
! --recursive_cnt;
|
|
Karsten Hopp |
634b72 |
return r;
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
case VAR_FUNC:
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 9391,9397 ****
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
for ( ; li != NULL; li = li->li_next)
|
|
Karsten Hopp |
634b72 |
! if (tv_equal(&li->li_tv, &argvars[1], ic))
|
|
Karsten Hopp |
634b72 |
++n;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
--- 9408,9414 ----
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
for ( ; li != NULL; li = li->li_next)
|
|
Karsten Hopp |
634b72 |
! if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE))
|
|
Karsten Hopp |
634b72 |
++n;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 9418,9424 ****
|
|
Karsten Hopp |
634b72 |
if (!HASHITEM_EMPTY(hi))
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
--todo;
|
|
Karsten Hopp |
634b72 |
! if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic))
|
|
Karsten Hopp |
634b72 |
++n;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
--- 9435,9441 ----
|
|
Karsten Hopp |
634b72 |
if (!HASHITEM_EMPTY(hi))
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
--todo;
|
|
Karsten Hopp |
634b72 |
! if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE))
|
|
Karsten Hopp |
634b72 |
++n;
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 12574,12580 ****
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
for ( ; item != NULL; item = item->li_next, ++idx)
|
|
Karsten Hopp |
634b72 |
! if (tv_equal(&item->li_tv, &argvars[1], ic))
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
rettv->vval.v_number = idx;
|
|
Karsten Hopp |
634b72 |
break;
|
|
Karsten Hopp |
634b72 |
--- 12591,12597 ----
|
|
Karsten Hopp |
634b72 |
}
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
for ( ; item != NULL; item = item->li_next, ++idx)
|
|
Karsten Hopp |
634b72 |
! if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE))
|
|
Karsten Hopp |
634b72 |
{
|
|
Karsten Hopp |
634b72 |
rettv->vval.v_number = idx;
|
|
Karsten Hopp |
634b72 |
break;
|
|
Karsten Hopp |
634b72 |
*** ../vim-7.3.054/src/testdir/test55.in 2010-08-15 21:57:29.000000000 +0200
|
|
Karsten Hopp |
634b72 |
--- src/testdir/test55.in 2010-11-10 20:15:27.000000000 +0100
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 342,348 ****
|
|
Karsten Hopp |
634b72 |
--- 342,359 ----
|
|
Karsten Hopp |
634b72 |
:$put =(d == d)
|
|
Karsten Hopp |
634b72 |
:$put =(l != deepcopy(l))
|
|
Karsten Hopp |
634b72 |
:$put =(d != deepcopy(d))
|
|
Karsten Hopp |
634b72 |
+ :"
|
|
Karsten Hopp |
634b72 |
+ :" compare complex recursively linked list and dict
|
|
Karsten Hopp |
634b72 |
+ :let l = []
|
|
Karsten Hopp |
634b72 |
+ :call add(l, l)
|
|
Karsten Hopp |
634b72 |
+ :let dict4 = {"l": l}
|
|
Karsten Hopp |
634b72 |
+ :call add(dict4.l, dict4)
|
|
Karsten Hopp |
634b72 |
+ :let lcopy = deepcopy(l)
|
|
Karsten Hopp |
634b72 |
+ :let dict4copy = deepcopy(dict4)
|
|
Karsten Hopp |
634b72 |
+ :$put =(l == lcopy)
|
|
Karsten Hopp |
634b72 |
+ :$put =(dict4 == dict4copy)
|
|
Karsten Hopp |
634b72 |
:endfun
|
|
Karsten Hopp |
634b72 |
+ :"
|
|
Karsten Hopp |
634b72 |
:call Test(1, 2, [3, 4], {5: 6}) " This may take a while
|
|
Karsten Hopp |
634b72 |
:"
|
|
Karsten Hopp |
634b72 |
:delfunc Test
|
|
Karsten Hopp |
634b72 |
*** ../vim-7.3.054/src/testdir/test55.ok 2010-08-15 21:57:29.000000000 +0200
|
|
Karsten Hopp |
634b72 |
--- src/testdir/test55.ok 2010-11-10 20:16:37.000000000 +0100
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 109,111 ****
|
|
Karsten Hopp |
634b72 |
--- 109,113 ----
|
|
Karsten Hopp |
634b72 |
1
|
|
Karsten Hopp |
634b72 |
0
|
|
Karsten Hopp |
634b72 |
0
|
|
Karsten Hopp |
634b72 |
+ 1
|
|
Karsten Hopp |
634b72 |
+ 1
|
|
Karsten Hopp |
634b72 |
*** ../vim-7.3.054/src/version.c 2010-11-10 18:59:50.000000000 +0100
|
|
Karsten Hopp |
634b72 |
--- src/version.c 2010-11-10 20:10:51.000000000 +0100
|
|
Karsten Hopp |
634b72 |
***************
|
|
Karsten Hopp |
634b72 |
*** 716,717 ****
|
|
Karsten Hopp |
634b72 |
--- 716,719 ----
|
|
Karsten Hopp |
634b72 |
{ /* Add new patch number below this line */
|
|
Karsten Hopp |
634b72 |
+ /**/
|
|
Karsten Hopp |
634b72 |
+ 55,
|
|
Karsten Hopp |
634b72 |
/**/
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
--
|
|
Karsten Hopp |
634b72 |
A special law prohibits unmarried women from parachuting on Sunday or she
|
|
Karsten Hopp |
634b72 |
shall risk arrest, fine, and/or jailing.
|
|
Karsten Hopp |
634b72 |
[real standing law in Florida, United States of America]
|
|
Karsten Hopp |
634b72 |
|
|
Karsten Hopp |
634b72 |
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
|
|
Karsten Hopp |
634b72 |
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
|
|
Karsten Hopp |
634b72 |
\\\ download, build and distribute -- http://www.A-A-P.org ///
|
|
Karsten Hopp |
634b72 |
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|