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

8e759ba865
This commit is contained in:
Michael Ennen
2016-10-29 12:02:58 -07:00
committed by James McCoy
parent b42347da45
commit 6c5dd6827f
3 changed files with 153 additions and 17 deletions

View File

@@ -3771,7 +3771,26 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
clear_tv(&var2);
return FAIL;
}
n1 = tv_equal(rettv, &var2, false, false);
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;
}
@@ -5151,6 +5170,61 @@ dict_equal (
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
@@ -5169,21 +5243,6 @@ tv_equal (
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.
@@ -5197,6 +5256,20 @@ tv_equal (
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:
++recursive_cnt;