# HG changeset patch # User Bram Moolenaar # Date 1577294104 -3600 # Node ID 6bd715870e3242d7efcde7e977c7fa411de89208 # Parent 0eb2333df312d308aa8fc0e1168251d85cb36691 patch 8.2.0044: expression type is used inconsistently Commit: https://github.com/vim/vim/commit/07a3db89b8953bd0964895badb3b662f7514bc10 Author: Bram Moolenaar Date: Wed Dec 25 18:14:14 2019 +0100 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. diff --git a/src/debugger.c b/src/debugger.c --- a/src/debugger.c +++ b/src/debugger.c @@ -929,8 +929,7 @@ debuggy_find( } else { - if (typval_compare(tv, bp->dbg_val, TYPE_EQUAL, - TRUE, FALSE) == OK + if (typval_compare(tv, bp->dbg_val, ETYPE_IS, FALSE) == OK && tv->vval.v_number == FALSE) { typval_T *v; diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -1997,8 +1997,7 @@ eval4(char_u **arg, typval_T *rettv, int typval_T var2; char_u *p; int i; - exptype_T type = TYPE_UNKNOWN; - int type_is = FALSE; // TRUE for "is" and "isnot" + exptype_T type = ETYPE_UNKNOWN; int len = 2; int ic; @@ -2012,30 +2011,30 @@ eval4(char_u **arg, typval_T *rettv, int switch (p[0]) { case '=': if (p[1] == '=') - type = TYPE_EQUAL; + type = ETYPE_EQUAL; else if (p[1] == '~') - type = TYPE_MATCH; + type = ETYPE_MATCH; break; case '!': if (p[1] == '=') - type = TYPE_NEQUAL; + type = ETYPE_NEQUAL; else if (p[1] == '~') - type = TYPE_NOMATCH; + type = ETYPE_NOMATCH; break; case '>': if (p[1] != '=') { - type = TYPE_GREATER; + type = ETYPE_GREATER; len = 1; } else - type = TYPE_GEQUAL; + type = ETYPE_GEQUAL; break; case '<': if (p[1] != '=') { - type = TYPE_SMALLER; + type = ETYPE_SMALLER; len = 1; } else - type = TYPE_SEQUAL; + type = ETYPE_SEQUAL; break; case 'i': if (p[1] == 's') { @@ -2043,10 +2042,7 @@ eval4(char_u **arg, typval_T *rettv, int len = 5; i = p[len]; if (!isalnum(i) && i != '_') - { - type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; - type_is = TRUE; - } + type = len == 2 ? ETYPE_IS : ETYPE_ISNOT; } break; } @@ -2054,7 +2050,7 @@ eval4(char_u **arg, typval_T *rettv, int /* * If there is a comparative operator, use it. */ - if (type != TYPE_UNKNOWN) + if (type != ETYPE_UNKNOWN) { // extra question mark appended: ignore case if (p[len] == '?') @@ -2083,7 +2079,7 @@ eval4(char_u **arg, typval_T *rettv, int } if (evaluate) { - int ret = typval_compare(rettv, &var2, type, type_is, ic); + int ret = typval_compare(rettv, &var2, type, ic); clear_tv(&var2); return ret; @@ -6163,19 +6159,19 @@ typval_compare( typval_T *typ1, // first operand typval_T *typ2, // second operand exptype_T type, // operator - int type_is, // TRUE for "is" and "isnot" int ic) // ignore case { int i; varnumber_T n1, n2; char_u *s1, *s2; char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; + int type_is = type == ETYPE_IS || type == ETYPE_ISNOT; if (type_is && typ1->v_type != typ2->v_type) { // For "is" a different type always means FALSE, for "notis" // it means TRUE. - n1 = (type == TYPE_NEQUAL); + n1 = (type == ETYPE_ISNOT); } 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 && typ1->vval.v_blob == typ2->vval.v_blob); - if (type == TYPE_NEQUAL) + if (type == ETYPE_ISNOT) n1 = !n1; } 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) emsg(_("E977: Can only compare Blob with Blob")); @@ -6200,7 +6196,7 @@ typval_compare( { // Compare two Blobs for being equal or unequal. n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob); - if (type == TYPE_NEQUAL) + if (type == ETYPE_NEQUAL) n1 = !n1; } } @@ -6210,11 +6206,11 @@ typval_compare( { n1 = (typ1->v_type == typ2->v_type && typ1->vval.v_list == typ2->vval.v_list); - if (type == TYPE_NEQUAL) + if (type == ETYPE_ISNOT) n1 = !n1; } 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) emsg(_("E691: Can only compare List with List")); @@ -6228,7 +6224,7 @@ typval_compare( // Compare two Lists for being equal or unequal. n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list, ic, FALSE); - if (type == TYPE_NEQUAL) + if (type == ETYPE_NEQUAL) n1 = !n1; } } @@ -6239,11 +6235,11 @@ typval_compare( { n1 = (typ1->v_type == typ2->v_type && typ1->vval.v_dict == typ2->vval.v_dict); - if (type == TYPE_NEQUAL) + if (type == ETYPE_ISNOT) n1 = !n1; } 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) emsg(_("E735: Can only compare Dictionary with Dictionary")); @@ -6257,7 +6253,7 @@ typval_compare( // Compare two Dictionaries for being equal or unequal. n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, ic, FALSE); - if (type == TYPE_NEQUAL) + if (type == ETYPE_NEQUAL) n1 = !n1; } } @@ -6265,7 +6261,7 @@ typval_compare( else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC || 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")); clear_tv(typ1); @@ -6291,7 +6287,7 @@ typval_compare( } else n1 = tv_equal(typ1, typ2, ic, FALSE); - if (type == TYPE_NEQUAL) + if (type == ETYPE_NEQUAL || type == ETYPE_ISNOT) n1 = !n1; } @@ -6301,7 +6297,7 @@ typval_compare( * When using "=~" or "!~", always compare as string. */ 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; @@ -6310,15 +6306,17 @@ typval_compare( n1 = FALSE; switch (type) { - case TYPE_EQUAL: n1 = (f1 == f2); break; - case TYPE_NEQUAL: n1 = (f1 != f2); break; - case TYPE_GREATER: n1 = (f1 > f2); break; - case TYPE_GEQUAL: n1 = (f1 >= f2); break; - case TYPE_SMALLER: n1 = (f1 < f2); break; - case TYPE_SEQUAL: n1 = (f1 <= f2); break; - case TYPE_UNKNOWN: - case TYPE_MATCH: - case TYPE_NOMATCH: break; // avoid gcc warning + case ETYPE_EQUAL: n1 = (f1 == f2); break; + case ETYPE_NEQUAL: n1 = (f1 != f2); break; + case ETYPE_GREATER: n1 = (f1 > f2); break; + case ETYPE_GEQUAL: n1 = (f1 >= f2); break; + case ETYPE_SMALLER: n1 = (f1 < f2); break; + case ETYPE_SEQUAL: n1 = (f1 <= f2); break; + case ETYPE_UNKNOWN: + case ETYPE_IS: + case ETYPE_ISNOT: + case ETYPE_MATCH: + case ETYPE_NOMATCH: break; // avoid gcc warning } } #endif @@ -6328,49 +6326,53 @@ typval_compare( * When using "=~" or "!~", always compare as string. */ 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); n2 = tv_get_number(typ2); switch (type) { - case TYPE_EQUAL: n1 = (n1 == n2); break; - case TYPE_NEQUAL: n1 = (n1 != n2); break; - case TYPE_GREATER: n1 = (n1 > n2); break; - case TYPE_GEQUAL: n1 = (n1 >= n2); break; - case TYPE_SMALLER: n1 = (n1 < n2); break; - case TYPE_SEQUAL: n1 = (n1 <= n2); break; - case TYPE_UNKNOWN: - case TYPE_MATCH: - case TYPE_NOMATCH: break; // avoid gcc warning + case ETYPE_EQUAL: n1 = (n1 == n2); break; + case ETYPE_NEQUAL: n1 = (n1 != n2); break; + case ETYPE_GREATER: n1 = (n1 > n2); break; + case ETYPE_GEQUAL: n1 = (n1 >= n2); break; + case ETYPE_SMALLER: n1 = (n1 < n2); break; + case ETYPE_SEQUAL: n1 = (n1 <= n2); break; + case ETYPE_UNKNOWN: + case ETYPE_IS: + case ETYPE_ISNOT: + case ETYPE_MATCH: + case ETYPE_NOMATCH: break; // avoid gcc warning } } else { s1 = tv_get_string_buf(typ1, buf1); 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); else i = 0; n1 = FALSE; switch (type) { - case TYPE_EQUAL: n1 = (i == 0); break; - case TYPE_NEQUAL: n1 = (i != 0); break; - case TYPE_GREATER: n1 = (i > 0); break; - case TYPE_GEQUAL: n1 = (i >= 0); break; - case TYPE_SMALLER: n1 = (i < 0); break; - case TYPE_SEQUAL: n1 = (i <= 0); break; - - case TYPE_MATCH: - case TYPE_NOMATCH: + case ETYPE_EQUAL: n1 = (i == 0); break; + case ETYPE_NEQUAL: n1 = (i != 0); break; + case ETYPE_GREATER: n1 = (i > 0); break; + case ETYPE_GEQUAL: n1 = (i >= 0); break; + case ETYPE_SMALLER: n1 = (i < 0); break; + case ETYPE_SEQUAL: n1 = (i <= 0); break; + + case ETYPE_MATCH: + case ETYPE_NOMATCH: n1 = pattern_match(s2, s1, ic); - if (type == TYPE_NOMATCH) + if (type == ETYPE_NOMATCH) n1 = !n1; break; - case TYPE_UNKNOWN: break; // avoid gcc warning + case ETYPE_IS: + case ETYPE_ISNOT: + case ETYPE_UNKNOWN: break; // avoid gcc warning } } clear_tv(typ1); diff --git a/src/proto/eval.pro b/src/proto/eval.pro --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -72,7 +72,7 @@ int get_echo_attr(void); void ex_execute(exarg_T *eap); char_u *find_option_end(char_u **arg, int *opt_flags); 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 *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags); /* vim: set ft=c : */ diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -3628,15 +3628,17 @@ typedef struct { */ typedef enum { - TYPE_UNKNOWN = 0, - TYPE_EQUAL, // == - TYPE_NEQUAL, // != - TYPE_GREATER, // > - TYPE_GEQUAL, // >= - TYPE_SMALLER, // < - TYPE_SEQUAL, // <= - TYPE_MATCH, // =~ - TYPE_NOMATCH, // !~ + ETYPE_UNKNOWN = 0, + ETYPE_EQUAL, // == + ETYPE_NEQUAL, // != + ETYPE_GREATER, // > + ETYPE_GEQUAL, // >= + ETYPE_SMALLER, // < + ETYPE_SEQUAL, // <= + ETYPE_MATCH, // =~ + ETYPE_NOMATCH, // !~ + ETYPE_IS, // is + ETYPE_ISNOT, // isnot } exptype_T; /* diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -743,6 +743,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 44, +/**/ 43, /**/ 42,