1
0
forked from aniani/vim

patch 9.1.1232: Vim script is missing the tuple data type

Problem:  Vim script is missing the tuple data type
Solution: Add support for the tuple data type
          (Yegappan Lakshmanan)

closes: #16776

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan
2025-03-23 16:42:16 +01:00
committed by Christian Brabandt
parent adb703e1b9
commit 9cb865e95b
75 changed files with 7155 additions and 691 deletions

View File

@@ -72,6 +72,9 @@ free_tv(typval_T *varp)
case VAR_LIST:
list_unref(varp->vval.v_list);
break;
case VAR_TUPLE:
tuple_unref(varp->vval.v_tuple);
break;
case VAR_DICT:
dict_unref(varp->vval.v_dict);
break;
@@ -138,6 +141,10 @@ clear_tv(typval_T *varp)
list_unref(varp->vval.v_list);
varp->vval.v_list = NULL;
break;
case VAR_TUPLE:
tuple_unref(varp->vval.v_tuple);
varp->vval.v_tuple = NULL;
break;
case VAR_DICT:
dict_unref(varp->vval.v_dict);
varp->vval.v_dict = NULL;
@@ -234,6 +241,9 @@ tv_get_bool_or_number_chk(
case VAR_LIST:
emsg(_(e_using_list_as_number));
break;
case VAR_TUPLE:
emsg(_(e_using_tuple_as_number));
break;
case VAR_DICT:
emsg(_(e_using_dictionary_as_number));
break;
@@ -368,6 +378,9 @@ tv_get_float_chk(typval_T *varp, int *error)
case VAR_LIST:
emsg(_(e_using_list_as_float));
break;
case VAR_TUPLE:
emsg(_(e_using_tuple_as_float));
break;
case VAR_DICT:
emsg(_(e_using_dictionary_as_float));
break;
@@ -529,7 +542,7 @@ check_for_bool_arg(typval_T *args, int idx)
/*
* Give an error and return FAIL unless "args[idx]" is a bool or a number.
*/
int
static int
check_for_bool_or_number_arg(typval_T *args, int idx)
{
if (args[idx].v_type != VAR_BOOL && args[idx].v_type != VAR_NUMBER)
@@ -619,6 +632,20 @@ check_for_opt_list_arg(typval_T *args, int idx)
|| check_for_list_arg(args, idx) != FAIL) ? OK : FAIL;
}
/*
* Give an error and return FAIL unless "args[idx]" is a tuple.
*/
int
check_for_tuple_arg(typval_T *args, int idx)
{
if (args[idx].v_type != VAR_TUPLE)
{
semsg(_(e_tuple_required_for_argument_nr), idx + 1);
return FAIL;
}
return OK;
}
/*
* Give an error and return FAIL unless "args[idx]" is a dict.
*/
@@ -827,17 +854,18 @@ check_for_string_or_list_arg(typval_T *args, int idx)
}
/*
* Give an error and return FAIL unless "args[idx]" is a string, a list or a
* blob.
* Give an error and return FAIL unless "args[idx]" is a string, a list, a
* tuple or a blob.
*/
int
check_for_string_or_list_or_blob_arg(typval_T *args, int idx)
check_for_string_or_list_or_tuple_or_blob_arg(typval_T *args, int idx)
{
if (args[idx].v_type != VAR_STRING
&& args[idx].v_type != VAR_LIST
&& args[idx].v_type != VAR_TUPLE
&& args[idx].v_type != VAR_BLOB)
{
semsg(_(e_string_list_or_blob_required_for_argument_nr), idx + 1);
semsg(_(e_string_list_tuple_or_blob_required_for_argument_nr), idx + 1);
return FAIL;
}
return OK;
@@ -897,35 +925,37 @@ check_for_opt_string_or_number_or_list_arg(typval_T *args, int idx)
}
/*
* Give an error and return FAIL unless "args[idx]" is a string or a number
* or a list or a blob.
* Give an error and return FAIL unless "args[idx]" is a string, a number, a
* list, a tuple or a blob.
*/
int
check_for_string_or_number_or_list_or_blob_arg(typval_T *args, int idx)
check_for_repeat_func_arg(typval_T *args, int idx)
{
if (args[idx].v_type != VAR_STRING
&& args[idx].v_type != VAR_NUMBER
&& args[idx].v_type != VAR_LIST
&& args[idx].v_type != VAR_TUPLE
&& args[idx].v_type != VAR_BLOB)
{
semsg(_(e_string_number_list_or_blob_required_for_argument_nr), idx + 1);
semsg(_(e_repeatable_type_required_for_argument_nr), idx + 1);
return FAIL;
}
return OK;
}
/*
* Give an error and return FAIL unless "args[idx]" is a string or a list
* or a dict.
* Give an error and return FAIL unless "args[idx]" is a string, a list, a
* tuple or a dict.
*/
int
check_for_string_or_list_or_dict_arg(typval_T *args, int idx)
check_for_string_list_tuple_or_dict_arg(typval_T *args, int idx)
{
if (args[idx].v_type != VAR_STRING
&& args[idx].v_type != VAR_LIST
&& args[idx].v_type != VAR_TUPLE
&& args[idx].v_type != VAR_DICT)
{
semsg(_(e_string_list_or_dict_required_for_argument_nr), idx + 1);
semsg(_(e_string_list_tuple_or_dict_required_for_argument_nr), idx + 1);
return FAIL;
}
return OK;
@@ -963,15 +993,48 @@ check_for_list_or_blob_arg(typval_T *args, int idx)
}
/*
* Give an error and return FAIL unless "args[idx]" is a list or dict
* Give an error and return FAIL unless "args[idx]" is a list or a tuple.
*/
int
check_for_list_or_dict_arg(typval_T *args, int idx)
check_for_list_or_tuple_arg(typval_T *args, int idx)
{
if (args[idx].v_type != VAR_LIST && args[idx].v_type != VAR_TUPLE)
{
semsg(_(e_list_or_tuple_required_for_argument_nr), idx + 1);
return FAIL;
}
return OK;
}
/*
* Give an error and return FAIL unless "args[idx]" is a list, a tuple or a
* blob.
*/
int
check_for_list_or_tuple_or_blob_arg(typval_T *args, int idx)
{
if (args[idx].v_type != VAR_LIST
&& args[idx].v_type != VAR_TUPLE
&& args[idx].v_type != VAR_BLOB)
{
semsg(_(e_list_or_tuple_or_blob_required_for_argument_nr), idx + 1);
return FAIL;
}
return OK;
}
/*
* Give an error and return FAIL unless "args[idx]" is a list, a tuple or a
* dict
*/
int
check_for_list_or_tuple_or_dict_arg(typval_T *args, int idx)
{
if (args[idx].v_type != VAR_LIST
&& args[idx].v_type != VAR_TUPLE
&& args[idx].v_type != VAR_DICT)
{
semsg(_(e_list_or_dict_required_for_argument_nr), idx + 1);
semsg(_(e_list_or_tuple_or_dict_required_for_argument_nr), idx + 1);
return FAIL;
}
return OK;
@@ -995,18 +1058,19 @@ check_for_list_or_dict_or_blob_arg(typval_T *args, int idx)
}
/*
* Give an error and return FAIL unless "args[idx]" is a list or dict or a
* blob or a string.
* Give an error and return FAIL unless "args[idx]" is a list, a tuple, a dict,
* a blob or a string.
*/
int
check_for_list_or_dict_or_blob_or_string_arg(typval_T *args, int idx)
check_for_list_tuple_dict_blob_or_string_arg(typval_T *args, int idx)
{
if (args[idx].v_type != VAR_LIST
&& args[idx].v_type != VAR_TUPLE
&& args[idx].v_type != VAR_DICT
&& args[idx].v_type != VAR_BLOB
&& args[idx].v_type != VAR_STRING)
{
semsg(_(e_list_dict_blob_or_string_required_for_argument_nr), idx + 1);
semsg(_(e_list_tuple_dict_blob_or_string_required_for_argument_nr), idx + 1);
return FAIL;
}
return OK;
@@ -1149,6 +1213,9 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
case VAR_LIST:
emsg(_(e_using_list_as_string));
break;
case VAR_TUPLE:
emsg(_(e_using_tuple_as_string));
break;
case VAR_DICT:
emsg(_(e_using_dictionary_as_string));
break;
@@ -1267,6 +1334,10 @@ tv_check_lock(typval_T *tv, char_u *name, int use_gettext)
if (tv->vval.v_list != NULL)
lock = tv->vval.v_list->lv_lock;
break;
case VAR_TUPLE:
if (tv->vval.v_tuple != NULL)
lock = tv->vval.v_tuple->tv_lock;
break;
case VAR_DICT:
if (tv->vval.v_dict != NULL)
lock = tv->vval.v_dict->dv_lock;
@@ -1364,6 +1435,15 @@ copy_tv(typval_T *from, typval_T *to)
++to->vval.v_list->lv_refcount;
}
break;
case VAR_TUPLE:
if (from->vval.v_tuple == NULL)
to->vval.v_tuple = NULL;
else
{
to->vval.v_tuple = from->vval.v_tuple;
++to->vval.v_tuple->tv_refcount;
}
break;
case VAR_DICT:
if (from->vval.v_dict == NULL)
to->vval.v_dict = NULL;
@@ -1452,6 +1532,15 @@ typval_compare(
}
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);
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)
@@ -1649,6 +1738,47 @@ typval_compare_list(
return OK;
}
/*
* Compare "tv1" to "tv2" as tuples according to "type" and "ic".
* Put the result, false or true, in "res".
* Return FAIL and give an error message when the comparison can't be done.
*/
int
typval_compare_tuple(
typval_T *tv1,
typval_T *tv2,
exprtype_T type,
int ic,
int *res)
{
int val = 0;
if (type == EXPR_IS || type == EXPR_ISNOT)
{
val = (tv1->v_type == tv2->v_type
&& tv1->vval.v_tuple == tv2->vval.v_tuple);
if (type == EXPR_ISNOT)
val = !val;
}
else if (tv1->v_type != tv2->v_type
|| (type != EXPR_EQUAL && type != EXPR_NEQUAL))
{
if (tv1->v_type != tv2->v_type)
emsg(_(e_can_only_compare_tuple_with_tuple));
else
emsg(_(e_invalid_operation_for_tuple));
return FAIL;
}
else
{
val = tuple_equal(tv1->vval.v_tuple, tv2->vval.v_tuple, ic);
if (type == EXPR_NEQUAL)
val = !val;
}
*res = val;
return OK;
}
/*
* Compare v:null with another type. Return TRUE if the value is NULL.
*/
@@ -1674,6 +1804,7 @@ typval_compare_null(typval_T *tv1, typval_T *tv2)
case VAR_JOB: return tv->vval.v_job == NULL;
#endif
case VAR_LIST: return tv->vval.v_list == NULL;
case VAR_TUPLE: return tv->vval.v_tuple == NULL;
case VAR_OBJECT: return tv->vval.v_object == NULL;
case VAR_PARTIAL: return tv->vval.v_partial == NULL;
case VAR_STRING: return tv->vval.v_string == NULL;
@@ -2078,6 +2209,12 @@ tv_equal(
--recursive_cnt;
return r;
case VAR_TUPLE:
++recursive_cnt;
r = tuple_equal(tv1->vval.v_tuple, tv2->vval.v_tuple, ic);
--recursive_cnt;
return r;
case VAR_DICT:
++recursive_cnt;
r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic);