summaryrefslogtreecommitdiffstats
path: root/src/typval.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-03-01 19:23:24 +0000
committerBram Moolenaar <Bram@vim.org>2022-03-01 19:23:24 +0000
commit7a2222487507eb13cccdb9a66397092775d62b8c (patch)
treec5878917461a22b48ec7a38cb6356352b8e57895 /src/typval.c
parentf01af9c4e6f1438cd1112cfff42f3837028c7846 (diff)
patch 8.2.4487: Vim9: cannot compare with v:nullv8.2.4487
Problem: Vim9: cannot compare with v:null. Solution: Allow comparing anything with v:null. (closes #9866)
Diffstat (limited to 'src/typval.c')
-rw-r--r--src/typval.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/typval.c b/src/typval.c
index ab226403df..775466784d 100644
--- a/src/typval.c
+++ b/src/typval.c
@@ -1169,6 +1169,21 @@ typval_compare(
// it means TRUE.
n1 = (type == EXPR_ISNOT);
}
+ else if (((tv1->v_type == VAR_SPECIAL && tv1->vval.v_number == VVAL_NULL)
+ || (tv2->v_type == VAR_SPECIAL
+ && tv2->vval.v_number == VVAL_NULL))
+ && tv1->v_type != tv2->v_type
+ && (type == EXPR_EQUAL || type == EXPR_NEQUAL))
+ {
+ n1 = typval_compare_null(tv1, tv2);
+ if (n1 == MAYBE)
+ {
+ clear_tv(tv1);
+ return FAIL;
+ }
+ if (type == EXPR_NEQUAL)
+ n1 = !n1;
+ }
else if (tv1->v_type == VAR_BLOB || tv2->v_type == VAR_BLOB)
{
if (typval_compare_blob(tv1, tv2, type, &res) == FAIL)
@@ -1366,6 +1381,35 @@ typval_compare_list(
}
/*
+ * Compare v:null/v:none with another type. Return TRUE if the value is NULL.
+ */
+ int
+typval_compare_null(typval_T *tv1, typval_T *tv2)
+{
+ if ((tv1->v_type == VAR_SPECIAL && tv1->vval.v_number == VVAL_NULL)
+ || (tv2->v_type == VAR_SPECIAL && tv2->vval.v_number == VVAL_NULL))
+ {
+ typval_T *tv = tv1->v_type == VAR_SPECIAL ? tv2 : tv1;
+
+ switch (tv->v_type)
+ {
+ case VAR_BLOB: return tv->vval.v_blob == NULL;
+ case VAR_CHANNEL: return tv->vval.v_channel == NULL;
+ case VAR_DICT: return tv->vval.v_dict == NULL;
+ case VAR_FUNC: return tv->vval.v_string == NULL;
+ case VAR_JOB: return tv->vval.v_job == NULL;
+ case VAR_LIST: return tv->vval.v_list == NULL;
+ case VAR_PARTIAL: return tv->vval.v_partial == NULL;
+ case VAR_STRING: return tv->vval.v_string == NULL;
+ default: break;
+ }
+ }
+ semsg(_(e_cannot_compare_str_with_str),
+ vartype_name(tv1->v_type), vartype_name(tv2->v_type));
+ return MAYBE;
+}
+
+/*
* Compare "tv1" to "tv2" as blobs acording to "type".
* Put the result, false or true, in "res".
* Return FAIL and give an error message when the comparison can't be done.