To: vim_dev@googlegroups.com Subject: Patch 8.2.0044 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0044 Problem: Expression type is used inconsistently. Solution: Add "ETYPE_IS" and "ETYPE_ISNOT" as separate enum values. Rename "TYPE_" to "ETYPE_" to avoid confusion. Files: src/structs.h, src/eval.c, src/proto/eval.pro, src/debugger.c *** ../vim-8.2.0043/src/structs.h 2019-12-20 19:06:54.288991943 +0100 --- src/structs.h 2019-12-25 18:00:38.868960641 +0100 *************** *** 3628,3642 **** */ typedef enum { ! TYPE_UNKNOWN = 0, ! TYPE_EQUAL, // == ! TYPE_NEQUAL, // != ! TYPE_GREATER, // > ! TYPE_GEQUAL, // >= ! TYPE_SMALLER, // < ! TYPE_SEQUAL, // <= ! TYPE_MATCH, // =~ ! TYPE_NOMATCH, // !~ } exptype_T; /* --- 3628,3644 ---- */ typedef enum { ! 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; /* *** ../vim-8.2.0043/src/eval.c 2019-12-22 15:38:02.350438554 +0100 --- src/eval.c 2019-12-25 18:02:34.884546106 +0100 *************** *** 1997,2004 **** typval_T var2; char_u *p; int i; ! exptype_T type = TYPE_UNKNOWN; ! int type_is = FALSE; // TRUE for "is" and "isnot" int len = 2; int ic; --- 1997,2003 ---- typval_T var2; char_u *p; int i; ! exptype_T type = ETYPE_UNKNOWN; int len = 2; int ic; *************** *** 2012,2041 **** switch (p[0]) { case '=': if (p[1] == '=') ! type = TYPE_EQUAL; else if (p[1] == '~') ! type = TYPE_MATCH; break; case '!': if (p[1] == '=') ! type = TYPE_NEQUAL; else if (p[1] == '~') ! type = TYPE_NOMATCH; break; case '>': if (p[1] != '=') { ! type = TYPE_GREATER; len = 1; } else ! type = TYPE_GEQUAL; break; case '<': if (p[1] != '=') { ! type = TYPE_SMALLER; len = 1; } else ! type = TYPE_SEQUAL; break; case 'i': if (p[1] == 's') { --- 2011,2040 ---- switch (p[0]) { case '=': if (p[1] == '=') ! type = ETYPE_EQUAL; else if (p[1] == '~') ! type = ETYPE_MATCH; break; case '!': if (p[1] == '=') ! type = ETYPE_NEQUAL; else if (p[1] == '~') ! type = ETYPE_NOMATCH; break; case '>': if (p[1] != '=') { ! type = ETYPE_GREATER; len = 1; } else ! type = ETYPE_GEQUAL; break; case '<': if (p[1] != '=') { ! type = ETYPE_SMALLER; len = 1; } else ! type = ETYPE_SEQUAL; break; case 'i': if (p[1] == 's') { *************** *** 2043,2052 **** len = 5; i = p[len]; if (!isalnum(i) && i != '_') ! { ! type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; ! type_is = TRUE; ! } } break; } --- 2042,2048 ---- len = 5; i = p[len]; if (!isalnum(i) && i != '_') ! type = len == 2 ? ETYPE_IS : ETYPE_ISNOT; } break; } *************** *** 2054,2060 **** /* * If there is a comparative operator, use it. */ ! if (type != TYPE_UNKNOWN) { // extra question mark appended: ignore case if (p[len] == '?') --- 2050,2056 ---- /* * If there is a comparative operator, use it. */ ! if (type != ETYPE_UNKNOWN) { // extra question mark appended: ignore case if (p[len] == '?') *************** *** 2083,2089 **** } if (evaluate) { ! int ret = typval_compare(rettv, &var2, type, type_is, ic); clear_tv(&var2); return ret; --- 2079,2085 ---- } if (evaluate) { ! int ret = typval_compare(rettv, &var2, type, ic); clear_tv(&var2); return ret; *************** *** 6163,6181 **** 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]; 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); } else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB) { --- 6159,6177 ---- typval_T *typ1, // first operand typval_T *typ2, // second operand exptype_T type, // operator 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 == ETYPE_ISNOT); } else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB) { *************** *** 6183,6193 **** { n1 = (typ1->v_type == typ2->v_type && typ1->vval.v_blob == typ2->vval.v_blob); ! if (type == TYPE_NEQUAL) n1 = !n1; } else if (typ1->v_type != typ2->v_type ! || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) { if (typ1->v_type != typ2->v_type) emsg(_("E977: Can only compare Blob with Blob")); --- 6179,6189 ---- { n1 = (typ1->v_type == typ2->v_type && typ1->vval.v_blob == typ2->vval.v_blob); ! if (type == ETYPE_ISNOT) n1 = !n1; } else if (typ1->v_type != typ2->v_type ! || (type != ETYPE_EQUAL && type != ETYPE_NEQUAL)) { if (typ1->v_type != typ2->v_type) emsg(_("E977: Can only compare Blob with Blob")); *************** *** 6200,6206 **** { // Compare two Blobs for being equal or unequal. n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob); ! if (type == TYPE_NEQUAL) n1 = !n1; } } --- 6196,6202 ---- { // Compare two Blobs for being equal or unequal. n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob); ! if (type == ETYPE_NEQUAL) n1 = !n1; } } *************** *** 6210,6220 **** { n1 = (typ1->v_type == typ2->v_type && typ1->vval.v_list == typ2->vval.v_list); ! if (type == TYPE_NEQUAL) n1 = !n1; } else if (typ1->v_type != typ2->v_type ! || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) { if (typ1->v_type != typ2->v_type) emsg(_("E691: Can only compare List with List")); --- 6206,6216 ---- { n1 = (typ1->v_type == typ2->v_type && typ1->vval.v_list == typ2->vval.v_list); ! if (type == ETYPE_ISNOT) n1 = !n1; } else if (typ1->v_type != typ2->v_type ! || (type != ETYPE_EQUAL && type != ETYPE_NEQUAL)) { if (typ1->v_type != typ2->v_type) emsg(_("E691: Can only compare List with List")); *************** *** 6228,6234 **** // 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) n1 = !n1; } } --- 6224,6230 ---- // Compare two Lists for being equal or unequal. n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list, ic, FALSE); ! if (type == ETYPE_NEQUAL) n1 = !n1; } } *************** *** 6239,6249 **** { n1 = (typ1->v_type == typ2->v_type && typ1->vval.v_dict == typ2->vval.v_dict); ! if (type == TYPE_NEQUAL) n1 = !n1; } else if (typ1->v_type != typ2->v_type ! || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) { if (typ1->v_type != typ2->v_type) emsg(_("E735: Can only compare Dictionary with Dictionary")); --- 6235,6245 ---- { n1 = (typ1->v_type == typ2->v_type && typ1->vval.v_dict == typ2->vval.v_dict); ! if (type == ETYPE_ISNOT) n1 = !n1; } else if (typ1->v_type != typ2->v_type ! || (type != ETYPE_EQUAL && type != ETYPE_NEQUAL)) { if (typ1->v_type != typ2->v_type) emsg(_("E735: Can only compare Dictionary with Dictionary")); *************** *** 6257,6263 **** // 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) n1 = !n1; } } --- 6253,6259 ---- // Compare two Dictionaries for being equal or unequal. n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, ic, FALSE); ! if (type == ETYPE_NEQUAL) n1 = !n1; } } *************** *** 6265,6271 **** 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) { emsg(_("E694: Invalid operation for Funcrefs")); clear_tv(typ1); --- 6261,6267 ---- else if (typ1->v_type == VAR_FUNC || typ2->v_type == VAR_FUNC || typ1->v_type == VAR_PARTIAL || typ2->v_type == VAR_PARTIAL) { ! if (type != ETYPE_EQUAL && type != ETYPE_NEQUAL) { emsg(_("E694: Invalid operation for Funcrefs")); clear_tv(typ1); *************** *** 6291,6297 **** } else n1 = tv_equal(typ1, typ2, ic, FALSE); ! if (type == TYPE_NEQUAL) n1 = !n1; } --- 6287,6293 ---- } else n1 = tv_equal(typ1, typ2, ic, FALSE); ! if (type == ETYPE_NEQUAL || type == ETYPE_ISNOT) n1 = !n1; } *************** *** 6301,6307 **** * 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) { float_T f1, f2; --- 6297,6303 ---- * When using "=~" or "!~", always compare as string. */ else if ((typ1->v_type == VAR_FLOAT || typ2->v_type == VAR_FLOAT) ! && type != ETYPE_MATCH && type != ETYPE_NOMATCH) { float_T f1, f2; *************** *** 6310,6324 **** 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 } } #endif --- 6306,6322 ---- n1 = FALSE; switch (type) { ! 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,6376 **** * 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) { 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 } } else { s1 = tv_get_string_buf(typ1, buf1); s2 = tv_get_string_buf(typ2, buf2); ! if (type != TYPE_MATCH && type != TYPE_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: n1 = pattern_match(s2, s1, ic); ! if (type == TYPE_NOMATCH) n1 = !n1; break; ! case TYPE_UNKNOWN: break; // avoid gcc warning } } clear_tv(typ1); --- 6326,6378 ---- * When using "=~" or "!~", always compare as string. */ else if ((typ1->v_type == VAR_NUMBER || typ2->v_type == VAR_NUMBER) ! && type != ETYPE_MATCH && type != ETYPE_NOMATCH) { n1 = tv_get_number(typ1); n2 = tv_get_number(typ2); switch (type) { ! 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 != ETYPE_MATCH && type != ETYPE_NOMATCH) i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); else i = 0; n1 = FALSE; switch (type) { ! 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 == ETYPE_NOMATCH) n1 = !n1; break; ! case ETYPE_IS: ! case ETYPE_ISNOT: ! case ETYPE_UNKNOWN: break; // avoid gcc warning } } clear_tv(typ1); *** ../vim-8.2.0043/src/proto/eval.pro 2019-12-12 12:55:18.000000000 +0100 --- src/proto/eval.pro 2019-12-25 17:58:46.241362546 +0100 *************** *** 72,78 **** 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); 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 : */ --- 72,78 ---- 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 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 : */ *** ../vim-8.2.0043/src/debugger.c 2019-05-24 18:11:26.000000000 +0200 --- src/debugger.c 2019-12-25 18:03:44.336297747 +0100 *************** *** 929,936 **** } else { ! if (typval_compare(tv, bp->dbg_val, TYPE_EQUAL, ! TRUE, FALSE) == OK && tv->vval.v_number == FALSE) { typval_T *v; --- 929,935 ---- } else { ! if (typval_compare(tv, bp->dbg_val, ETYPE_IS, FALSE) == OK && tv->vval.v_number == FALSE) { typval_T *v; *** ../vim-8.2.0043/src/version.c 2019-12-25 15:46:57.870500645 +0100 --- src/version.c 2019-12-25 17:59:43.701157585 +0100 *************** *** 744,745 **** --- 744,747 ---- { /* Add new patch number below this line */ + /**/ + 44, /**/ -- Shit makes the flowers grow and that's beautiful /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 ///