mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	Merge pull request #14339 from janlazo/vim-8.2.0044
vim-patch:8.2.{44,45,69,2319}
			
			
This commit is contained in:
		
							
								
								
									
										141
									
								
								src/nvim/eval.c
									
									
									
									
									
								
							
							
						
						
									
										141
									
								
								src/nvim/eval.c
									
									
									
									
									
								
							| @@ -3417,8 +3417,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) | |||||||
| { | { | ||||||
|   typval_T var2; |   typval_T var2; | ||||||
|   char_u      *p; |   char_u      *p; | ||||||
|   exptype_T type = TYPE_UNKNOWN; |   exprtype_T type = EXPR_UNKNOWN; | ||||||
|   bool type_is = false;             // true for "is" and "isnot" |  | ||||||
|   int len = 2; |   int len = 2; | ||||||
|   bool ic; |   bool ic; | ||||||
|  |  | ||||||
| @@ -3430,35 +3429,42 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) | |||||||
|  |  | ||||||
|   p = *arg; |   p = *arg; | ||||||
|   switch (p[0]) { |   switch (p[0]) { | ||||||
|   case '=':   if (p[1] == '=') |   case '=': | ||||||
|       type = TYPE_EQUAL; |     if (p[1] == '=') { | ||||||
|     else if (p[1] == '~') |       type = EXPR_EQUAL; | ||||||
|       type = TYPE_MATCH; |     } else if (p[1] == '~') { | ||||||
|  |       type = EXPR_MATCH; | ||||||
|  |     } | ||||||
|     break; |     break; | ||||||
|   case '!':   if (p[1] == '=') |   case '!': | ||||||
|       type = TYPE_NEQUAL; |     if (p[1] == '=') { | ||||||
|     else if (p[1] == '~') |       type = EXPR_NEQUAL; | ||||||
|       type = TYPE_NOMATCH; |     } else if (p[1] == '~') { | ||||||
|  |       type = EXPR_NOMATCH; | ||||||
|  |     } | ||||||
|     break; |     break; | ||||||
|   case '>':   if (p[1] != '=') { |   case '>': | ||||||
|       type = TYPE_GREATER; |     if (p[1] != '=') { | ||||||
|  |       type = EXPR_GREATER; | ||||||
|       len = 1; |       len = 1; | ||||||
|   } else |     } else { | ||||||
|       type = TYPE_GEQUAL; |       type = EXPR_GEQUAL; | ||||||
|  |     } | ||||||
|     break; |     break; | ||||||
|   case '<':   if (p[1] != '=') { |   case '<': | ||||||
|       type = TYPE_SMALLER; |     if (p[1] != '=') { | ||||||
|  |       type = EXPR_SMALLER; | ||||||
|       len = 1; |       len = 1; | ||||||
|   } else |     } else { | ||||||
|       type = TYPE_SEQUAL; |       type = EXPR_SEQUAL; | ||||||
|  |     } | ||||||
|     break; |     break; | ||||||
|   case 'i':   if (p[1] == 's') { |   case 'i':   if (p[1] == 's') { | ||||||
|       if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') { |       if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') { | ||||||
|         len = 5; |         len = 5; | ||||||
|       } |       } | ||||||
|       if (!isalnum(p[len]) && p[len] != '_') { |       if (!isalnum(p[len]) && p[len] != '_') { | ||||||
|         type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; |         type = len == 2 ? EXPR_IS : EXPR_ISNOT; | ||||||
|         type_is = true; |  | ||||||
|       } |       } | ||||||
|   } |   } | ||||||
|     break; |     break; | ||||||
| @@ -3467,7 +3473,7 @@ static int 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 != EXPR_UNKNOWN) { | ||||||
|     // extra question mark appended: ignore case |     // extra question mark appended: ignore case | ||||||
|     if (p[len] == '?') { |     if (p[len] == '?') { | ||||||
|       ic = true; |       ic = true; | ||||||
| @@ -3486,7 +3492,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) | |||||||
|       return FAIL; |       return FAIL; | ||||||
|     } |     } | ||||||
|     if (evaluate) { |     if (evaluate) { | ||||||
|       const int ret = typval_compare(rettv, &var2, type, type_is, ic); |       const int ret = typval_compare(rettv, &var2, type, ic); | ||||||
|  |  | ||||||
|       tv_clear(&var2); |       tv_clear(&var2); | ||||||
|       return ret; |       return ret; | ||||||
| @@ -10582,27 +10588,27 @@ bool invoke_prompt_interrupt(void) | |||||||
| int typval_compare( | int 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 |     exprtype_T type,  // operator | ||||||
|     bool type_is,     // true for "is" and "isnot" |  | ||||||
|     bool ic           // ignore case |     bool ic           // ignore case | ||||||
| ) | ) | ||||||
|   FUNC_ATTR_NONNULL_ALL |   FUNC_ATTR_NONNULL_ALL | ||||||
| { | { | ||||||
|   varnumber_T n1, n2; |   varnumber_T n1, n2; | ||||||
|  |   const bool type_is = type == EXPR_IS || type == EXPR_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 == EXPR_ISNOT; | ||||||
|   } else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) { |   } else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) { | ||||||
|     if (type_is) { |     if (type_is) { | ||||||
|       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 == EXPR_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 != EXPR_EQUAL && type != EXPR_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")); | ||||||
|       } else { |       } else { | ||||||
| @@ -10613,7 +10619,7 @@ int typval_compare( | |||||||
|     } else { |     } else { | ||||||
|       // Compare two Lists for being equal or unequal. |       // Compare two Lists for being equal or unequal. | ||||||
|       n1 = tv_list_equal(typ1->vval.v_list, typ2->vval.v_list, ic, false); |       n1 = tv_list_equal(typ1->vval.v_list, typ2->vval.v_list, ic, false); | ||||||
|       if (type == TYPE_NEQUAL) { |       if (type == EXPR_NEQUAL) { | ||||||
|         n1 = !n1; |         n1 = !n1; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -10621,11 +10627,11 @@ int typval_compare( | |||||||
|     if (type_is) { |     if (type_is) { | ||||||
|       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 == EXPR_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 != EXPR_EQUAL && type != EXPR_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")); | ||||||
|       } else { |       } else { | ||||||
| @@ -10636,12 +10642,13 @@ int typval_compare( | |||||||
|     } else { |     } else { | ||||||
|       // Compare two Dictionaries for being equal or unequal. |       // Compare two Dictionaries for being equal or unequal. | ||||||
|       n1 = tv_dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, ic, false); |       n1 = tv_dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, ic, false); | ||||||
|       if (type == TYPE_NEQUAL) { |       if (type == EXPR_NEQUAL) { | ||||||
|         n1 = !n1; |         n1 = !n1; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } else if (tv_is_func(*typ1) || tv_is_func(*typ2)) { |   } else if (tv_is_func(*typ1) || tv_is_func(*typ2)) { | ||||||
|     if (type != TYPE_EQUAL && type != TYPE_NEQUAL) { |     if (type != EXPR_EQUAL && type != EXPR_NEQUAL | ||||||
|  |         && type != EXPR_IS && type != EXPR_ISNOT) { | ||||||
|       EMSG(_("E694: Invalid operation for Funcrefs")); |       EMSG(_("E694: Invalid operation for Funcrefs")); | ||||||
|       tv_clear(typ1); |       tv_clear(typ1); | ||||||
|       return FAIL; |       return FAIL; | ||||||
| @@ -10663,43 +10670,47 @@ int typval_compare( | |||||||
|     } else { |     } else { | ||||||
|       n1 = tv_equal(typ1, typ2, ic, false); |       n1 = tv_equal(typ1, typ2, ic, false); | ||||||
|     } |     } | ||||||
|     if (type == TYPE_NEQUAL) { |     if (type == EXPR_NEQUAL || type == EXPR_ISNOT) { | ||||||
|       n1 = !n1; |       n1 = !n1; | ||||||
|     } |     } | ||||||
|   } 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 != EXPR_MATCH && type != EXPR_NOMATCH) { | ||||||
|     // If one of the two variables is a float, compare as a float. |     // If one of the two variables is a float, compare as a float. | ||||||
|     // When using "=~" or "!~", always compare as string. |     // When using "=~" or "!~", always compare as string. | ||||||
|     const float_T f1 = tv_get_float(typ1); |     const float_T f1 = tv_get_float(typ1); | ||||||
|     const float_T f2 = tv_get_float(typ2); |     const float_T f2 = tv_get_float(typ2); | ||||||
|     n1 = false; |     n1 = false; | ||||||
|     switch (type) { |     switch (type) { | ||||||
|       case TYPE_EQUAL:    n1 = f1 == f2; break; |       case EXPR_IS: | ||||||
|       case TYPE_NEQUAL:   n1 = f1 != f2; break; |       case EXPR_EQUAL:    n1 = f1 == f2; break; | ||||||
|       case TYPE_GREATER:  n1 = f1 > f2; break; |       case EXPR_ISNOT: | ||||||
|       case TYPE_GEQUAL:   n1 = f1 >= f2; break; |       case EXPR_NEQUAL:   n1 = f1 != f2; break; | ||||||
|       case TYPE_SMALLER:  n1 = f1 < f2; break; |       case EXPR_GREATER:  n1 = f1 > f2; break; | ||||||
|       case TYPE_SEQUAL:   n1 = f1 <= f2; break; |       case EXPR_GEQUAL:   n1 = f1 >= f2; break; | ||||||
|       case TYPE_UNKNOWN: |       case EXPR_SMALLER:  n1 = f1 < f2; break; | ||||||
|       case TYPE_MATCH: |       case EXPR_SEQUAL:   n1 = f1 <= f2; break; | ||||||
|       case TYPE_NOMATCH:  break; |       case EXPR_UNKNOWN: | ||||||
|  |       case EXPR_MATCH: | ||||||
|  |       case EXPR_NOMATCH:  break;  // avoid gcc warning | ||||||
|     } |     } | ||||||
|   } 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 != EXPR_MATCH && type != EXPR_NOMATCH) { | ||||||
|     // If one of the two variables is a number, compare as a number. |     // If one of the two variables is a number, compare as a number. | ||||||
|     // When using "=~" or "!~", always compare as string. |     // When using "=~" or "!~", always compare as string. | ||||||
|     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 EXPR_IS: | ||||||
|       case TYPE_NEQUAL:   n1 = n1 != n2; break; |       case EXPR_EQUAL:    n1 = n1 == n2; break; | ||||||
|       case TYPE_GREATER:  n1 = n1 > n2; break; |       case EXPR_ISNOT: | ||||||
|       case TYPE_GEQUAL:   n1 = n1 >= n2; break; |       case EXPR_NEQUAL:   n1 = n1 != n2; break; | ||||||
|       case TYPE_SMALLER:  n1 = n1 < n2; break; |       case EXPR_GREATER:  n1 = n1 > n2; break; | ||||||
|       case TYPE_SEQUAL:   n1 = n1 <= n2; break; |       case EXPR_GEQUAL:   n1 = n1 >= n2; break; | ||||||
|       case TYPE_UNKNOWN: |       case EXPR_SMALLER:  n1 = n1 < n2; break; | ||||||
|       case TYPE_MATCH: |       case EXPR_SEQUAL:   n1 = n1 <= n2; break; | ||||||
|       case TYPE_NOMATCH:  break; |       case EXPR_UNKNOWN: | ||||||
|  |       case EXPR_MATCH: | ||||||
|  |       case EXPR_NOMATCH:  break;  // avoid gcc warning | ||||||
|     } |     } | ||||||
|   } else { |   } else { | ||||||
|     char buf1[NUMBUFLEN]; |     char buf1[NUMBUFLEN]; | ||||||
| @@ -10707,28 +10718,30 @@ int typval_compare( | |||||||
|     const char *const s1 = tv_get_string_buf(typ1, buf1); |     const char *const s1 = tv_get_string_buf(typ1, buf1); | ||||||
|     const char *const s2 = tv_get_string_buf(typ2, buf2); |     const char *const s2 = tv_get_string_buf(typ2, buf2); | ||||||
|     int i; |     int i; | ||||||
|     if (type != TYPE_MATCH && type != TYPE_NOMATCH) { |     if (type != EXPR_MATCH && type != EXPR_NOMATCH) { | ||||||
|       i = mb_strcmp_ic(ic, s1, s2); |       i = mb_strcmp_ic(ic, s1, s2); | ||||||
|     } else { |     } else { | ||||||
|       i = 0; |       i = 0; | ||||||
|     } |     } | ||||||
|     n1 = false; |     n1 = false; | ||||||
|     switch (type) { |     switch (type) { | ||||||
|       case TYPE_EQUAL:    n1 = i == 0; break; |       case EXPR_IS: | ||||||
|       case TYPE_NEQUAL:   n1 = i != 0; break; |       case EXPR_EQUAL:    n1 = i == 0; break; | ||||||
|       case TYPE_GREATER:  n1 = i > 0; break; |       case EXPR_ISNOT: | ||||||
|       case TYPE_GEQUAL:   n1 = i >= 0; break; |       case EXPR_NEQUAL:   n1 = i != 0; break; | ||||||
|       case TYPE_SMALLER:  n1 = i < 0; break; |       case EXPR_GREATER:  n1 = i > 0; break; | ||||||
|       case TYPE_SEQUAL:   n1 = i <= 0; break; |       case EXPR_GEQUAL:   n1 = i >= 0; break; | ||||||
|  |       case EXPR_SMALLER:  n1 = i < 0; break; | ||||||
|  |       case EXPR_SEQUAL:   n1 = i <= 0; break; | ||||||
|  |  | ||||||
|       case TYPE_MATCH: |       case EXPR_MATCH: | ||||||
|       case TYPE_NOMATCH: |       case EXPR_NOMATCH: | ||||||
|         n1 = pattern_match((char_u *)s2, (char_u *)s1, ic); |         n1 = pattern_match((char_u *)s2, (char_u *)s1, ic); | ||||||
|         if (type == TYPE_NOMATCH) { |         if (type == EXPR_NOMATCH) { | ||||||
|           n1 = !n1; |           n1 = !n1; | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|       case TYPE_UNKNOWN: break;  // Avoid gcc warning. |       case EXPR_UNKNOWN:  break;  // avoid gcc warning | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   tv_clear(typ1); |   tv_clear(typ1); | ||||||
|   | |||||||
| @@ -230,16 +230,18 @@ typedef enum | |||||||
|  |  | ||||||
| /// types for expressions. | /// types for expressions. | ||||||
| typedef enum { | typedef enum { | ||||||
|   TYPE_UNKNOWN = 0, |   EXPR_UNKNOWN = 0, | ||||||
|   TYPE_EQUAL,         ///< == |   EXPR_EQUAL,         ///< == | ||||||
|   TYPE_NEQUAL,        ///< != |   EXPR_NEQUAL,        ///< != | ||||||
|   TYPE_GREATER,       ///< > |   EXPR_GREATER,       ///< > | ||||||
|   TYPE_GEQUAL,        ///< >= |   EXPR_GEQUAL,        ///< >= | ||||||
|   TYPE_SMALLER,       ///< < |   EXPR_SMALLER,       ///< < | ||||||
|   TYPE_SEQUAL,        ///< <= |   EXPR_SEQUAL,        ///< <= | ||||||
|   TYPE_MATCH,         ///< =~ |   EXPR_MATCH,         ///< =~ | ||||||
|   TYPE_NOMATCH,       ///< !~ |   EXPR_NOMATCH,       ///< !~ | ||||||
| } exptype_T; |   EXPR_IS,            ///< is | ||||||
|  |   EXPR_ISNOT,         ///< isnot | ||||||
|  | } exprtype_T; | ||||||
|  |  | ||||||
| /// Type for dict_list function | /// Type for dict_list function | ||||||
| typedef enum { | typedef enum { | ||||||
|   | |||||||
| @@ -876,7 +876,7 @@ debuggy_find( | |||||||
|           debug_newval = typval_tostring(bp->dbg_val); |           debug_newval = typval_tostring(bp->dbg_val); | ||||||
|           line = true; |           line = true; | ||||||
|         } else { |         } else { | ||||||
|           if (typval_compare(tv, bp->dbg_val, TYPE_EQUAL, true, false) == OK |           if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK | ||||||
|               && tv->vval.v_number == false) { |               && tv->vval.v_number == false) { | ||||||
|             line = true; |             line = true; | ||||||
|             debug_oldval = typval_tostring(bp->dbg_val); |             debug_oldval = typval_tostring(bp->dbg_val); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jan Edmund Lazo
					Jan Edmund Lazo