mirror of
https://github.com/vim/vim.git
synced 2025-10-27 09:24:23 -04:00
patch 9.1.1684: min()/max() does not handle float data types
Problem: min()/max() does not handle float data types
(ubaldot)
Solution: Extend min() and max() to every comparable type
(LemonBoy)
Re-use the logic used for plain old comparison operators, this way we
gain support for float values and unify the logic handling the
comparisons.
fixes: #18052
closes: 18055
Signed-off-by: LemonBoy <thatlemon@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
b922b30cfe
commit
3b3b936125
99
src/typval.c
99
src/typval.c
@@ -1475,30 +1475,26 @@ copy_tv(typval_T *from, typval_T *to)
|
||||
|
||||
/*
|
||||
* Compare "tv1" and "tv2".
|
||||
* Put the result in "tv1". Caller should clear "tv2".
|
||||
*/
|
||||
int
|
||||
typval_compare(
|
||||
typval_compare2(
|
||||
typval_T *tv1, // first operand
|
||||
typval_T *tv2, // second operand
|
||||
exprtype_T type, // operator
|
||||
int ic) // ignore case
|
||||
exprtype_T type, // operator
|
||||
int ic, // ignore case
|
||||
int *res) // comparison result
|
||||
{
|
||||
varnumber_T n1, n2;
|
||||
int res = 0;
|
||||
int type_is = type == EXPR_IS || type == EXPR_ISNOT;
|
||||
|
||||
if (check_typval_is_value(tv1) == FAIL
|
||||
|| check_typval_is_value(tv2) == FAIL)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
return FAIL;
|
||||
}
|
||||
else if (type_is && tv1->v_type != tv2->v_type)
|
||||
{
|
||||
// For "is" a different type always means FALSE, for "isnot"
|
||||
// it means TRUE.
|
||||
n1 = (type == EXPR_ISNOT);
|
||||
*res = (type == EXPR_ISNOT);
|
||||
}
|
||||
else if (((tv1->v_type == VAR_SPECIAL && tv1->vval.v_number == VVAL_NULL)
|
||||
|| (tv2->v_type == VAR_SPECIAL
|
||||
@@ -1508,67 +1504,41 @@ typval_compare(
|
||||
{
|
||||
n1 = typval_compare_null(tv1, tv2);
|
||||
if (n1 == MAYBE)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
return FAIL;
|
||||
}
|
||||
if (type == EXPR_NEQUAL)
|
||||
n1 = !n1;
|
||||
*res = n1;
|
||||
}
|
||||
else if (tv1->v_type == VAR_BLOB || tv2->v_type == VAR_BLOB)
|
||||
{
|
||||
if (typval_compare_blob(tv1, tv2, type, &res) == FAIL)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
if (typval_compare_blob(tv1, tv2, type, res) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
n1 = res;
|
||||
}
|
||||
else if (tv1->v_type == VAR_LIST || tv2->v_type == VAR_LIST)
|
||||
{
|
||||
if (typval_compare_list(tv1, tv2, type, ic, &res) == FAIL)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
if (typval_compare_list(tv1, tv2, type, ic, res) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
n1 = res;
|
||||
}
|
||||
else if (tv1->v_type == VAR_TUPLE || tv2->v_type == VAR_TUPLE)
|
||||
{
|
||||
if (typval_compare_tuple(tv1, tv2, type, ic, &res) == FAIL)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
if (typval_compare_tuple(tv1, tv2, type, ic, res) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
n1 = res;
|
||||
}
|
||||
else if (tv1->v_type == VAR_OBJECT || tv2->v_type == VAR_OBJECT)
|
||||
{
|
||||
if (typval_compare_object(tv1, tv2, type, ic, &res) == FAIL)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
if (typval_compare_object(tv1, tv2, type, ic, res) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
n1 = res;
|
||||
}
|
||||
else if (tv1->v_type == VAR_DICT || tv2->v_type == VAR_DICT)
|
||||
{
|
||||
if (typval_compare_dict(tv1, tv2, type, ic, &res) == FAIL)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
if (typval_compare_dict(tv1, tv2, type, ic, res) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
n1 = res;
|
||||
}
|
||||
else if (tv1->v_type == VAR_FUNC || tv2->v_type == VAR_FUNC
|
||||
|| tv1->v_type == VAR_PARTIAL || tv2->v_type == VAR_PARTIAL)
|
||||
{
|
||||
if (typval_compare_func(tv1, tv2, type, ic, &res) == FAIL)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
if (typval_compare_func(tv1, tv2, type, ic, res) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
n1 = res;
|
||||
}
|
||||
|
||||
// If one of the two variables is a float, compare as a float.
|
||||
@@ -1583,10 +1553,7 @@ typval_compare(
|
||||
if (!error)
|
||||
f2 = tv_get_float_chk(tv2, &error);
|
||||
if (error)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
return FAIL;
|
||||
}
|
||||
n1 = FALSE;
|
||||
switch (type)
|
||||
{
|
||||
@@ -1602,6 +1569,7 @@ typval_compare(
|
||||
case EXPR_MATCH:
|
||||
default: break; // avoid gcc warning
|
||||
}
|
||||
*res = n1;
|
||||
}
|
||||
|
||||
// If one of the two variables is a number, compare as a number.
|
||||
@@ -1615,10 +1583,7 @@ typval_compare(
|
||||
if (!error)
|
||||
n2 = tv_get_number_chk(tv2, &error);
|
||||
if (error)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
return FAIL;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case EXPR_IS:
|
||||
@@ -1633,6 +1598,7 @@ typval_compare(
|
||||
case EXPR_MATCH:
|
||||
default: break; // avoid gcc warning
|
||||
}
|
||||
*res = n1;
|
||||
}
|
||||
else if (in_vim9script() && (tv1->v_type == VAR_BOOL
|
||||
|| tv2->v_type == VAR_BOOL
|
||||
@@ -1643,7 +1609,6 @@ typval_compare(
|
||||
{
|
||||
semsg(_(e_cannot_compare_str_with_str),
|
||||
vartype_name(tv1->v_type), vartype_name(tv2->v_type));
|
||||
clear_tv(tv1);
|
||||
return FAIL;
|
||||
}
|
||||
n1 = tv1->vval.v_number;
|
||||
@@ -1657,9 +1622,9 @@ typval_compare(
|
||||
default:
|
||||
semsg(_(e_invalid_operation_for_str),
|
||||
vartype_name(tv1->v_type));
|
||||
clear_tv(tv1);
|
||||
return FAIL;
|
||||
}
|
||||
*res = n1;
|
||||
}
|
||||
#ifdef FEAT_JOB_CHANNEL
|
||||
else if (tv1->v_type == tv2->v_type
|
||||
@@ -1672,27 +1637,47 @@ typval_compare(
|
||||
n1 = tv1->vval.v_job == tv2->vval.v_job;
|
||||
if (type == EXPR_NEQUAL)
|
||||
n1 = !n1;
|
||||
*res = n1;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
if (typval_compare_string(tv1, tv2, type, ic, &res) == FAIL)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
if (typval_compare_string(tv1, tv2, type, ic, res) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
n1 = res;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare "tv1" and "tv2".
|
||||
* Put the result in "tv1". Caller should clear "tv2".
|
||||
*/
|
||||
int
|
||||
typval_compare(
|
||||
typval_T *tv1, // first operand
|
||||
typval_T *tv2, // second operand
|
||||
exprtype_T type, // operator
|
||||
int ic) // ignore case
|
||||
{
|
||||
int res;
|
||||
|
||||
if (typval_compare2(tv1, tv2, type, ic, &res) == FAIL)
|
||||
{
|
||||
clear_tv(tv1);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
clear_tv(tv1);
|
||||
if (in_vim9script())
|
||||
{
|
||||
tv1->v_type = VAR_BOOL;
|
||||
tv1->vval.v_number = n1 ? VVAL_TRUE : VVAL_FALSE;
|
||||
tv1->vval.v_number = res ? VVAL_TRUE : VVAL_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
tv1->v_type = VAR_NUMBER;
|
||||
tv1->vval.v_number = n1;
|
||||
tv1->vval.v_number = res;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
Reference in New Issue
Block a user