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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201912251714.xBPHEmos001903%40masaka.moolenaar.net.

Raspunde prin e-mail lui