mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.0044: expression type is used inconsistently
Problem: Expression type is used inconsistently. Solution: Add "ETYPE_IS" and "ETYPE_ISNOT" as separate enum values. Rename "TYPE_" to "ETYPE_" to avoid confusion.
This commit is contained in:
@@ -929,8 +929,7 @@ debuggy_find(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (typval_compare(tv, bp->dbg_val, TYPE_EQUAL,
|
if (typval_compare(tv, bp->dbg_val, ETYPE_IS, FALSE) == OK
|
||||||
TRUE, FALSE) == OK
|
|
||||||
&& tv->vval.v_number == FALSE)
|
&& tv->vval.v_number == FALSE)
|
||||||
{
|
{
|
||||||
typval_T *v;
|
typval_T *v;
|
||||||
|
122
src/eval.c
122
src/eval.c
@@ -1997,8 +1997,7 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
typval_T var2;
|
typval_T var2;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
int i;
|
int i;
|
||||||
exptype_T type = TYPE_UNKNOWN;
|
exptype_T type = ETYPE_UNKNOWN;
|
||||||
int type_is = FALSE; // TRUE for "is" and "isnot"
|
|
||||||
int len = 2;
|
int len = 2;
|
||||||
int ic;
|
int ic;
|
||||||
|
|
||||||
@@ -2012,30 +2011,30 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
switch (p[0])
|
switch (p[0])
|
||||||
{
|
{
|
||||||
case '=': if (p[1] == '=')
|
case '=': if (p[1] == '=')
|
||||||
type = TYPE_EQUAL;
|
type = ETYPE_EQUAL;
|
||||||
else if (p[1] == '~')
|
else if (p[1] == '~')
|
||||||
type = TYPE_MATCH;
|
type = ETYPE_MATCH;
|
||||||
break;
|
break;
|
||||||
case '!': if (p[1] == '=')
|
case '!': if (p[1] == '=')
|
||||||
type = TYPE_NEQUAL;
|
type = ETYPE_NEQUAL;
|
||||||
else if (p[1] == '~')
|
else if (p[1] == '~')
|
||||||
type = TYPE_NOMATCH;
|
type = ETYPE_NOMATCH;
|
||||||
break;
|
break;
|
||||||
case '>': if (p[1] != '=')
|
case '>': if (p[1] != '=')
|
||||||
{
|
{
|
||||||
type = TYPE_GREATER;
|
type = ETYPE_GREATER;
|
||||||
len = 1;
|
len = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
type = TYPE_GEQUAL;
|
type = ETYPE_GEQUAL;
|
||||||
break;
|
break;
|
||||||
case '<': if (p[1] != '=')
|
case '<': if (p[1] != '=')
|
||||||
{
|
{
|
||||||
type = TYPE_SMALLER;
|
type = ETYPE_SMALLER;
|
||||||
len = 1;
|
len = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
type = TYPE_SEQUAL;
|
type = ETYPE_SEQUAL;
|
||||||
break;
|
break;
|
||||||
case 'i': if (p[1] == 's')
|
case 'i': if (p[1] == 's')
|
||||||
{
|
{
|
||||||
@@ -2043,10 +2042,7 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
len = 5;
|
len = 5;
|
||||||
i = p[len];
|
i = p[len];
|
||||||
if (!isalnum(i) && i != '_')
|
if (!isalnum(i) && i != '_')
|
||||||
{
|
type = len == 2 ? ETYPE_IS : ETYPE_ISNOT;
|
||||||
type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL;
|
|
||||||
type_is = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2054,7 +2050,7 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
/*
|
/*
|
||||||
* If there is a comparative operator, use it.
|
* If there is a comparative operator, use it.
|
||||||
*/
|
*/
|
||||||
if (type != TYPE_UNKNOWN)
|
if (type != ETYPE_UNKNOWN)
|
||||||
{
|
{
|
||||||
// extra question mark appended: ignore case
|
// extra question mark appended: ignore case
|
||||||
if (p[len] == '?')
|
if (p[len] == '?')
|
||||||
@@ -2083,7 +2079,7 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
}
|
}
|
||||||
if (evaluate)
|
if (evaluate)
|
||||||
{
|
{
|
||||||
int ret = typval_compare(rettv, &var2, type, type_is, ic);
|
int ret = typval_compare(rettv, &var2, type, ic);
|
||||||
|
|
||||||
clear_tv(&var2);
|
clear_tv(&var2);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -6163,19 +6159,19 @@ typval_compare(
|
|||||||
typval_T *typ1, // first operand
|
typval_T *typ1, // first operand
|
||||||
typval_T *typ2, // second operand
|
typval_T *typ2, // second operand
|
||||||
exptype_T type, // operator
|
exptype_T type, // operator
|
||||||
int type_is, // TRUE for "is" and "isnot"
|
|
||||||
int ic) // ignore case
|
int ic) // ignore case
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
varnumber_T n1, n2;
|
varnumber_T n1, n2;
|
||||||
char_u *s1, *s2;
|
char_u *s1, *s2;
|
||||||
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
|
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
|
||||||
|
int type_is = type == ETYPE_IS || type == ETYPE_ISNOT;
|
||||||
|
|
||||||
if (type_is && typ1->v_type != typ2->v_type)
|
if (type_is && typ1->v_type != typ2->v_type)
|
||||||
{
|
{
|
||||||
// For "is" a different type always means FALSE, for "notis"
|
// For "is" a different type always means FALSE, for "notis"
|
||||||
// it means TRUE.
|
// it means TRUE.
|
||||||
n1 = (type == TYPE_NEQUAL);
|
n1 = (type == ETYPE_ISNOT);
|
||||||
}
|
}
|
||||||
else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
|
else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
|
||||||
{
|
{
|
||||||
@@ -6183,11 +6179,11 @@ typval_compare(
|
|||||||
{
|
{
|
||||||
n1 = (typ1->v_type == typ2->v_type
|
n1 = (typ1->v_type == typ2->v_type
|
||||||
&& typ1->vval.v_blob == typ2->vval.v_blob);
|
&& typ1->vval.v_blob == typ2->vval.v_blob);
|
||||||
if (type == TYPE_NEQUAL)
|
if (type == ETYPE_ISNOT)
|
||||||
n1 = !n1;
|
n1 = !n1;
|
||||||
}
|
}
|
||||||
else if (typ1->v_type != typ2->v_type
|
else if (typ1->v_type != typ2->v_type
|
||||||
|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
|
|| (type != ETYPE_EQUAL && type != ETYPE_NEQUAL))
|
||||||
{
|
{
|
||||||
if (typ1->v_type != typ2->v_type)
|
if (typ1->v_type != typ2->v_type)
|
||||||
emsg(_("E977: Can only compare Blob with Blob"));
|
emsg(_("E977: Can only compare Blob with Blob"));
|
||||||
@@ -6200,7 +6196,7 @@ typval_compare(
|
|||||||
{
|
{
|
||||||
// Compare two Blobs for being equal or unequal.
|
// Compare two Blobs for being equal or unequal.
|
||||||
n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
|
n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
|
||||||
if (type == TYPE_NEQUAL)
|
if (type == ETYPE_NEQUAL)
|
||||||
n1 = !n1;
|
n1 = !n1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6210,11 +6206,11 @@ typval_compare(
|
|||||||
{
|
{
|
||||||
n1 = (typ1->v_type == typ2->v_type
|
n1 = (typ1->v_type == typ2->v_type
|
||||||
&& typ1->vval.v_list == typ2->vval.v_list);
|
&& typ1->vval.v_list == typ2->vval.v_list);
|
||||||
if (type == TYPE_NEQUAL)
|
if (type == ETYPE_ISNOT)
|
||||||
n1 = !n1;
|
n1 = !n1;
|
||||||
}
|
}
|
||||||
else if (typ1->v_type != typ2->v_type
|
else if (typ1->v_type != typ2->v_type
|
||||||
|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
|
|| (type != ETYPE_EQUAL && type != ETYPE_NEQUAL))
|
||||||
{
|
{
|
||||||
if (typ1->v_type != typ2->v_type)
|
if (typ1->v_type != typ2->v_type)
|
||||||
emsg(_("E691: Can only compare List with List"));
|
emsg(_("E691: Can only compare List with List"));
|
||||||
@@ -6228,7 +6224,7 @@ typval_compare(
|
|||||||
// Compare two Lists for being equal or unequal.
|
// Compare two Lists for being equal or unequal.
|
||||||
n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
|
n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list,
|
||||||
ic, FALSE);
|
ic, FALSE);
|
||||||
if (type == TYPE_NEQUAL)
|
if (type == ETYPE_NEQUAL)
|
||||||
n1 = !n1;
|
n1 = !n1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6239,11 +6235,11 @@ typval_compare(
|
|||||||
{
|
{
|
||||||
n1 = (typ1->v_type == typ2->v_type
|
n1 = (typ1->v_type == typ2->v_type
|
||||||
&& typ1->vval.v_dict == typ2->vval.v_dict);
|
&& typ1->vval.v_dict == typ2->vval.v_dict);
|
||||||
if (type == TYPE_NEQUAL)
|
if (type == ETYPE_ISNOT)
|
||||||
n1 = !n1;
|
n1 = !n1;
|
||||||
}
|
}
|
||||||
else if (typ1->v_type != typ2->v_type
|
else if (typ1->v_type != typ2->v_type
|
||||||
|| (type != TYPE_EQUAL && type != TYPE_NEQUAL))
|
|| (type != ETYPE_EQUAL && type != ETYPE_NEQUAL))
|
||||||
{
|
{
|
||||||
if (typ1->v_type != typ2->v_type)
|
if (typ1->v_type != typ2->v_type)
|
||||||
emsg(_("E735: Can only compare Dictionary with Dictionary"));
|
emsg(_("E735: Can only compare Dictionary with Dictionary"));
|
||||||
@@ -6257,7 +6253,7 @@ typval_compare(
|
|||||||
// Compare two Dictionaries for being equal or unequal.
|
// Compare two Dictionaries for being equal or unequal.
|
||||||
n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
|
n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict,
|
||||||
ic, FALSE);
|
ic, FALSE);
|
||||||
if (type == TYPE_NEQUAL)
|
if (type == ETYPE_NEQUAL)
|
||||||
n1 = !n1;
|
n1 = !n1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6265,7 +6261,7 @@ typval_compare(
|
|||||||
else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
|
else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC
|
||||||
|| typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
|
|| typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL)
|
||||||
{
|
{
|
||||||
if (type != TYPE_EQUAL && type != TYPE_NEQUAL)
|
if (type != ETYPE_EQUAL && type != ETYPE_NEQUAL)
|
||||||
{
|
{
|
||||||
emsg(_("E694: Invalid operation for Funcrefs"));
|
emsg(_("E694: Invalid operation for Funcrefs"));
|
||||||
clear_tv(typ1);
|
clear_tv(typ1);
|
||||||
@@ -6291,7 +6287,7 @@ typval_compare(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
n1 = tv_equal(typ1, typ2, ic, FALSE);
|
n1 = tv_equal(typ1, typ2, ic, FALSE);
|
||||||
if (type == TYPE_NEQUAL)
|
if (type == ETYPE_NEQUAL || type == ETYPE_ISNOT)
|
||||||
n1 = !n1;
|
n1 = !n1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6301,7 +6297,7 @@ typval_compare(
|
|||||||
* When using "=~" or "!~", always compare as string.
|
* When using "=~" or "!~", always compare as string.
|
||||||
*/
|
*/
|
||||||
else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
|
else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT)
|
||||||
&& type != TYPE_MATCH && type != TYPE_NOMATCH)
|
&& type != ETYPE_MATCH && type != ETYPE_NOMATCH)
|
||||||
{
|
{
|
||||||
float_T f1, f2;
|
float_T f1, f2;
|
||||||
|
|
||||||
@@ -6310,15 +6306,17 @@ typval_compare(
|
|||||||
n1 = FALSE;
|
n1 = FALSE;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TYPE_EQUAL: n1 = (f1 == f2); break;
|
case ETYPE_EQUAL: n1 = (f1 == f2); break;
|
||||||
case TYPE_NEQUAL: n1 = (f1 != f2); break;
|
case ETYPE_NEQUAL: n1 = (f1 != f2); break;
|
||||||
case TYPE_GREATER: n1 = (f1 > f2); break;
|
case ETYPE_GREATER: n1 = (f1 > f2); break;
|
||||||
case TYPE_GEQUAL: n1 = (f1 >= f2); break;
|
case ETYPE_GEQUAL: n1 = (f1 >= f2); break;
|
||||||
case TYPE_SMALLER: n1 = (f1 < f2); break;
|
case ETYPE_SMALLER: n1 = (f1 < f2); break;
|
||||||
case TYPE_SEQUAL: n1 = (f1 <= f2); break;
|
case ETYPE_SEQUAL: n1 = (f1 <= f2); break;
|
||||||
case TYPE_UNKNOWN:
|
case ETYPE_UNKNOWN:
|
||||||
case TYPE_MATCH:
|
case ETYPE_IS:
|
||||||
case TYPE_NOMATCH: break; // avoid gcc warning
|
case ETYPE_ISNOT:
|
||||||
|
case ETYPE_MATCH:
|
||||||
|
case ETYPE_NOMATCH: break; // avoid gcc warning
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -6328,49 +6326,53 @@ typval_compare(
|
|||||||
* When using "=~" or "!~", always compare as string.
|
* When using "=~" or "!~", always compare as string.
|
||||||
*/
|
*/
|
||||||
else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
|
else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER)
|
||||||
&& type != TYPE_MATCH && type != TYPE_NOMATCH)
|
&& type != ETYPE_MATCH && type != ETYPE_NOMATCH)
|
||||||
{
|
{
|
||||||
n1 = tv_get_number(typ1);
|
n1 = tv_get_number(typ1);
|
||||||
n2 = tv_get_number(typ2);
|
n2 = tv_get_number(typ2);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TYPE_EQUAL: n1 = (n1 == n2); break;
|
case ETYPE_EQUAL: n1 = (n1 == n2); break;
|
||||||
case TYPE_NEQUAL: n1 = (n1 != n2); break;
|
case ETYPE_NEQUAL: n1 = (n1 != n2); break;
|
||||||
case TYPE_GREATER: n1 = (n1 > n2); break;
|
case ETYPE_GREATER: n1 = (n1 > n2); break;
|
||||||
case TYPE_GEQUAL: n1 = (n1 >= n2); break;
|
case ETYPE_GEQUAL: n1 = (n1 >= n2); break;
|
||||||
case TYPE_SMALLER: n1 = (n1 < n2); break;
|
case ETYPE_SMALLER: n1 = (n1 < n2); break;
|
||||||
case TYPE_SEQUAL: n1 = (n1 <= n2); break;
|
case ETYPE_SEQUAL: n1 = (n1 <= n2); break;
|
||||||
case TYPE_UNKNOWN:
|
case ETYPE_UNKNOWN:
|
||||||
case TYPE_MATCH:
|
case ETYPE_IS:
|
||||||
case TYPE_NOMATCH: break; // avoid gcc warning
|
case ETYPE_ISNOT:
|
||||||
|
case ETYPE_MATCH:
|
||||||
|
case ETYPE_NOMATCH: break; // avoid gcc warning
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s1 = tv_get_string_buf(typ1, buf1);
|
s1 = tv_get_string_buf(typ1, buf1);
|
||||||
s2 = tv_get_string_buf(typ2, buf2);
|
s2 = tv_get_string_buf(typ2, buf2);
|
||||||
if (type != TYPE_MATCH && type != TYPE_NOMATCH)
|
if (type != ETYPE_MATCH && type != ETYPE_NOMATCH)
|
||||||
i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
|
i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2);
|
||||||
else
|
else
|
||||||
i = 0;
|
i = 0;
|
||||||
n1 = FALSE;
|
n1 = FALSE;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TYPE_EQUAL: n1 = (i == 0); break;
|
case ETYPE_EQUAL: n1 = (i == 0); break;
|
||||||
case TYPE_NEQUAL: n1 = (i != 0); break;
|
case ETYPE_NEQUAL: n1 = (i != 0); break;
|
||||||
case TYPE_GREATER: n1 = (i > 0); break;
|
case ETYPE_GREATER: n1 = (i > 0); break;
|
||||||
case TYPE_GEQUAL: n1 = (i >= 0); break;
|
case ETYPE_GEQUAL: n1 = (i >= 0); break;
|
||||||
case TYPE_SMALLER: n1 = (i < 0); break;
|
case ETYPE_SMALLER: n1 = (i < 0); break;
|
||||||
case TYPE_SEQUAL: n1 = (i <= 0); break;
|
case ETYPE_SEQUAL: n1 = (i <= 0); break;
|
||||||
|
|
||||||
case TYPE_MATCH:
|
case ETYPE_MATCH:
|
||||||
case TYPE_NOMATCH:
|
case ETYPE_NOMATCH:
|
||||||
n1 = pattern_match(s2, s1, ic);
|
n1 = pattern_match(s2, s1, ic);
|
||||||
if (type == TYPE_NOMATCH)
|
if (type == ETYPE_NOMATCH)
|
||||||
n1 = !n1;
|
n1 = !n1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_UNKNOWN: break; // avoid gcc warning
|
case ETYPE_IS:
|
||||||
|
case ETYPE_ISNOT:
|
||||||
|
case ETYPE_UNKNOWN: break; // avoid gcc warning
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clear_tv(typ1);
|
clear_tv(typ1);
|
||||||
|
@@ -72,7 +72,7 @@ int get_echo_attr(void);
|
|||||||
void ex_execute(exarg_T *eap);
|
void ex_execute(exarg_T *eap);
|
||||||
char_u *find_option_end(char_u **arg, int *opt_flags);
|
char_u *find_option_end(char_u **arg, int *opt_flags);
|
||||||
void last_set_msg(sctx_T script_ctx);
|
void last_set_msg(sctx_T script_ctx);
|
||||||
int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int type_is, int ic);
|
int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int ic);
|
||||||
char_u *typval_tostring(typval_T *arg);
|
char_u *typval_tostring(typval_T *arg);
|
||||||
char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags);
|
char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -3628,15 +3628,17 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
TYPE_UNKNOWN = 0,
|
ETYPE_UNKNOWN = 0,
|
||||||
TYPE_EQUAL, // ==
|
ETYPE_EQUAL, // ==
|
||||||
TYPE_NEQUAL, // !=
|
ETYPE_NEQUAL, // !=
|
||||||
TYPE_GREATER, // >
|
ETYPE_GREATER, // >
|
||||||
TYPE_GEQUAL, // >=
|
ETYPE_GEQUAL, // >=
|
||||||
TYPE_SMALLER, // <
|
ETYPE_SMALLER, // <
|
||||||
TYPE_SEQUAL, // <=
|
ETYPE_SEQUAL, // <=
|
||||||
TYPE_MATCH, // =~
|
ETYPE_MATCH, // =~
|
||||||
TYPE_NOMATCH, // !~
|
ETYPE_NOMATCH, // !~
|
||||||
|
ETYPE_IS, // is
|
||||||
|
ETYPE_ISNOT, // isnot
|
||||||
} exptype_T;
|
} exptype_T;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -742,6 +742,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
44,
|
||||||
/**/
|
/**/
|
||||||
43,
|
43,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user