mirror of
https://github.com/vim/vim.git
synced 2025-09-29 04:34:16 -04:00
patch 7.4.1267
Problem: Easy to miss handling all types of variables. Solution: Change the variable type into an enum.
This commit is contained in:
217
src/eval.c
217
src/eval.c
@@ -3065,6 +3065,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
|
|||||||
case VAR_DICT:
|
case VAR_DICT:
|
||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
|
case VAR_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
@@ -3837,6 +3838,14 @@ item_lock(typval_T *tv, int deep, int lock)
|
|||||||
|
|
||||||
switch (tv->v_type)
|
switch (tv->v_type)
|
||||||
{
|
{
|
||||||
|
case VAR_UNKNOWN:
|
||||||
|
case VAR_NUMBER:
|
||||||
|
case VAR_STRING:
|
||||||
|
case VAR_FUNC:
|
||||||
|
case VAR_FLOAT:
|
||||||
|
case VAR_SPECIAL:
|
||||||
|
break;
|
||||||
|
|
||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
if ((l = tv->vval.v_list) != NULL)
|
if ((l = tv->vval.v_list) != NULL)
|
||||||
{
|
{
|
||||||
@@ -5317,23 +5326,32 @@ eval_index(
|
|||||||
char_u *s;
|
char_u *s;
|
||||||
char_u *key = NULL;
|
char_u *key = NULL;
|
||||||
|
|
||||||
if (rettv->v_type == VAR_FUNC)
|
switch (rettv->v_type)
|
||||||
{
|
{
|
||||||
if (verbose)
|
case VAR_FUNC:
|
||||||
EMSG(_("E695: Cannot index a Funcref"));
|
if (verbose)
|
||||||
return FAIL;
|
EMSG(_("E695: Cannot index a Funcref"));
|
||||||
}
|
return FAIL;
|
||||||
|
case VAR_FLOAT:
|
||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
else if (rettv->v_type == VAR_FLOAT)
|
if (verbose)
|
||||||
{
|
EMSG(_(e_float_as_string));
|
||||||
if (verbose)
|
return FAIL;
|
||||||
EMSG(_(e_float_as_string));
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
else if (rettv->v_type == VAR_SPECIAL)
|
case VAR_SPECIAL:
|
||||||
{
|
if (verbose)
|
||||||
return FAIL;
|
EMSG(_("E909: Cannot index a special variable"));
|
||||||
|
return FAIL;
|
||||||
|
case VAR_UNKNOWN:
|
||||||
|
if (evaluate)
|
||||||
|
return FAIL;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case VAR_STRING:
|
||||||
|
case VAR_NUMBER:
|
||||||
|
case VAR_LIST:
|
||||||
|
case VAR_DICT:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_tv(&var1);
|
init_tv(&var1);
|
||||||
@@ -5428,6 +5446,12 @@ eval_index(
|
|||||||
|
|
||||||
switch (rettv->v_type)
|
switch (rettv->v_type)
|
||||||
{
|
{
|
||||||
|
case VAR_SPECIAL:
|
||||||
|
case VAR_FUNC:
|
||||||
|
case VAR_FLOAT:
|
||||||
|
case VAR_UNKNOWN:
|
||||||
|
break; /* not evaluating, skipping over subscript */
|
||||||
|
|
||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
case VAR_STRING:
|
case VAR_STRING:
|
||||||
s = get_tv_string(rettv);
|
s = get_tv_string(rettv);
|
||||||
@@ -6143,6 +6167,9 @@ tv_equal(
|
|||||||
|
|
||||||
switch (tv1->v_type)
|
switch (tv1->v_type)
|
||||||
{
|
{
|
||||||
|
case VAR_UNKNOWN:
|
||||||
|
break;
|
||||||
|
|
||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
++recursive_cnt;
|
++recursive_cnt;
|
||||||
r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
|
r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
|
||||||
@@ -6177,8 +6204,9 @@ tv_equal(
|
|||||||
return tv1->vval.v_number == tv2->vval.v_number;
|
return tv1->vval.v_number == tv2->vval.v_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSG2(_(e_intern2), "tv_equal()");
|
/* VAR_UNKNOWN can be the result of a invalid expression, let's say it
|
||||||
return TRUE;
|
* does not equal anything, not even itself. */
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7047,59 +7075,56 @@ set_ref_in_item(
|
|||||||
list_T *ll;
|
list_T *ll;
|
||||||
int abort = FALSE;
|
int abort = FALSE;
|
||||||
|
|
||||||
switch (tv->v_type)
|
if (tv->v_type == VAR_DICT)
|
||||||
{
|
{
|
||||||
case VAR_DICT:
|
dd = tv->vval.v_dict;
|
||||||
dd = tv->vval.v_dict;
|
if (dd != NULL && dd->dv_copyID != copyID)
|
||||||
if (dd != NULL && dd->dv_copyID != copyID)
|
{
|
||||||
|
/* Didn't see this dict yet. */
|
||||||
|
dd->dv_copyID = copyID;
|
||||||
|
if (ht_stack == NULL)
|
||||||
{
|
{
|
||||||
/* Didn't see this dict yet. */
|
abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
|
||||||
dd->dv_copyID = copyID;
|
}
|
||||||
if (ht_stack == NULL)
|
else
|
||||||
{
|
{
|
||||||
abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
|
ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T));
|
||||||
}
|
if (newitem == NULL)
|
||||||
|
abort = TRUE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ht_stack_T *newitem = (ht_stack_T*)malloc(
|
newitem->ht = &dd->dv_hashtab;
|
||||||
sizeof(ht_stack_T));
|
newitem->prev = *ht_stack;
|
||||||
if (newitem == NULL)
|
*ht_stack = newitem;
|
||||||
abort = TRUE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newitem->ht = &dd->dv_hashtab;
|
|
||||||
newitem->prev = *ht_stack;
|
|
||||||
*ht_stack = newitem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
case VAR_LIST:
|
else if (tv->v_type == VAR_LIST)
|
||||||
ll = tv->vval.v_list;
|
{
|
||||||
if (ll != NULL && ll->lv_copyID != copyID)
|
ll = tv->vval.v_list;
|
||||||
|
if (ll != NULL && ll->lv_copyID != copyID)
|
||||||
|
{
|
||||||
|
/* Didn't see this list yet. */
|
||||||
|
ll->lv_copyID = copyID;
|
||||||
|
if (list_stack == NULL)
|
||||||
{
|
{
|
||||||
/* Didn't see this list yet. */
|
abort = set_ref_in_list(ll, copyID, ht_stack);
|
||||||
ll->lv_copyID = copyID;
|
}
|
||||||
if (list_stack == NULL)
|
else
|
||||||
{
|
{
|
||||||
abort = set_ref_in_list(ll, copyID, ht_stack);
|
list_stack_T *newitem = (list_stack_T*)malloc(
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
list_stack_T *newitem = (list_stack_T*)malloc(
|
|
||||||
sizeof(list_stack_T));
|
sizeof(list_stack_T));
|
||||||
if (newitem == NULL)
|
if (newitem == NULL)
|
||||||
abort = TRUE;
|
abort = TRUE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newitem->list = ll;
|
newitem->list = ll;
|
||||||
newitem->prev = *list_stack;
|
newitem->prev = *list_stack;
|
||||||
*list_stack = newitem;
|
*list_stack = newitem;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
return abort;
|
return abort;
|
||||||
}
|
}
|
||||||
@@ -7763,6 +7788,7 @@ echo_string(
|
|||||||
|
|
||||||
case VAR_STRING:
|
case VAR_STRING:
|
||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
|
case VAR_UNKNOWN:
|
||||||
*tofree = NULL;
|
*tofree = NULL;
|
||||||
r = get_tv_string_buf(tv, numbuf);
|
r = get_tv_string_buf(tv, numbuf);
|
||||||
break;
|
break;
|
||||||
@@ -7779,10 +7805,6 @@ echo_string(
|
|||||||
*tofree = NULL;
|
*tofree = NULL;
|
||||||
r = (char_u *)get_var_special_name(tv->vval.v_number);
|
r = (char_u *)get_var_special_name(tv->vval.v_number);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
EMSG2(_(e_intern2), "echo_string()");
|
|
||||||
*tofree = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--recurse == 0)
|
if (--recurse == 0)
|
||||||
@@ -7822,9 +7844,8 @@ tv2string(
|
|||||||
case VAR_LIST:
|
case VAR_LIST:
|
||||||
case VAR_DICT:
|
case VAR_DICT:
|
||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
|
case VAR_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
EMSG2(_(e_intern2), "tv2string()");
|
|
||||||
}
|
}
|
||||||
return echo_string(tv, tofree, numbuf, copyID);
|
return echo_string(tv, tofree, numbuf, copyID);
|
||||||
}
|
}
|
||||||
@@ -10528,9 +10549,10 @@ f_empty(typval_T *argvars, typval_T *rettv)
|
|||||||
n = argvars[0].vval.v_number != VVAL_TRUE;
|
n = argvars[0].vval.v_number != VVAL_TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case VAR_UNKNOWN:
|
||||||
EMSG2(_(e_intern2), "f_empty()");
|
EMSG2(_(e_intern2), "f_empty(UNKNOWN)");
|
||||||
n = 0;
|
n = TRUE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rettv->vval.v_number = n;
|
rettv->vval.v_number = n;
|
||||||
@@ -14266,7 +14288,10 @@ f_len(typval_T *argvars, typval_T *rettv)
|
|||||||
case VAR_DICT:
|
case VAR_DICT:
|
||||||
rettv->vval.v_number = dict_len(argvars[0].vval.v_dict);
|
rettv->vval.v_number = dict_len(argvars[0].vval.v_dict);
|
||||||
break;
|
break;
|
||||||
default:
|
case VAR_UNKNOWN:
|
||||||
|
case VAR_SPECIAL:
|
||||||
|
case VAR_FLOAT:
|
||||||
|
case VAR_FUNC:
|
||||||
EMSG(_("E701: Invalid type for len()"));
|
EMSG(_("E701: Invalid type for len()"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -19624,13 +19649,16 @@ f_type(typval_T *argvars, typval_T *rettv)
|
|||||||
case VAR_FLOAT: n = 5; break;
|
case VAR_FLOAT: n = 5; break;
|
||||||
#endif
|
#endif
|
||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
if (argvars[0].vval.v_number == VVAL_FALSE
|
if (argvars[0].vval.v_number == VVAL_FALSE
|
||||||
|| argvars[0].vval.v_number == VVAL_TRUE)
|
|| argvars[0].vval.v_number == VVAL_TRUE)
|
||||||
n = 6;
|
n = 6;
|
||||||
else
|
else
|
||||||
n = 7;
|
n = 7;
|
||||||
break;
|
break;
|
||||||
default: EMSG2(_(e_intern2), "f_type()"); n = 0; break;
|
case VAR_UNKNOWN:
|
||||||
|
EMSG2(_(e_intern2), "f_type(UNKNOWN)");
|
||||||
|
n = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
rettv->vval.v_number = n;
|
rettv->vval.v_number = n;
|
||||||
}
|
}
|
||||||
@@ -21000,9 +21028,6 @@ free_tv(typval_T *varp)
|
|||||||
case VAR_UNKNOWN:
|
case VAR_UNKNOWN:
|
||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
EMSG2(_(e_intern2), "free_tv()");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
vim_free(varp);
|
vim_free(varp);
|
||||||
}
|
}
|
||||||
@@ -21044,8 +21069,6 @@ clear_tv(typval_T *varp)
|
|||||||
#endif
|
#endif
|
||||||
case VAR_UNKNOWN:
|
case VAR_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
EMSG2(_(e_intern2), "clear_tv()");
|
|
||||||
}
|
}
|
||||||
varp->v_lock = 0;
|
varp->v_lock = 0;
|
||||||
}
|
}
|
||||||
@@ -21108,8 +21131,8 @@ get_tv_number_chk(typval_T *varp, int *denote)
|
|||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
|
return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
default:
|
case VAR_UNKNOWN:
|
||||||
EMSG2(_(e_intern2), "get_tv_number()");
|
EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (denote == NULL) /* useful for values that must be unsigned */
|
if (denote == NULL) /* useful for values that must be unsigned */
|
||||||
@@ -21130,7 +21153,6 @@ get_tv_float(typval_T *varp)
|
|||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
case VAR_FLOAT:
|
case VAR_FLOAT:
|
||||||
return varp->vval.v_float;
|
return varp->vval.v_float;
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
EMSG(_("E891: Using a Funcref as a Float"));
|
EMSG(_("E891: Using a Funcref as a Float"));
|
||||||
@@ -21144,8 +21166,11 @@ get_tv_float(typval_T *varp)
|
|||||||
case VAR_DICT:
|
case VAR_DICT:
|
||||||
EMSG(_("E894: Using a Dictionary as a Float"));
|
EMSG(_("E894: Using a Dictionary as a Float"));
|
||||||
break;
|
break;
|
||||||
default:
|
case VAR_SPECIAL:
|
||||||
EMSG2(_(e_intern2), "get_tv_float()");
|
EMSG(_("E907: Using a special value as a Float"));
|
||||||
|
break;
|
||||||
|
case VAR_UNKNOWN:
|
||||||
|
EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -21256,9 +21281,8 @@ get_tv_string_buf_chk(typval_T *varp, char_u *buf)
|
|||||||
case VAR_SPECIAL:
|
case VAR_SPECIAL:
|
||||||
STRCPY(buf, get_var_special_name(varp->vval.v_number));
|
STRCPY(buf, get_var_special_name(varp->vval.v_number));
|
||||||
return buf;
|
return buf;
|
||||||
|
case VAR_UNKNOWN:
|
||||||
default:
|
EMSG(_("E908: using an invalid value as a String"));
|
||||||
EMSG2(_(e_intern2), "get_tv_string_buf()");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -21910,8 +21934,8 @@ copy_tv(typval_T *from, typval_T *to)
|
|||||||
++to->vval.v_dict->dv_refcount;
|
++to->vval.v_dict->dv_refcount;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
case VAR_UNKNOWN:
|
||||||
EMSG2(_(e_intern2), "copy_tv()");
|
EMSG2(_(e_intern2), "copy_tv(UNKNOWN)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21983,8 +22007,8 @@ item_copy(
|
|||||||
if (to->vval.v_dict == NULL)
|
if (to->vval.v_dict == NULL)
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
break;
|
break;
|
||||||
default:
|
case VAR_UNKNOWN:
|
||||||
EMSG2(_(e_intern2), "item_copy()");
|
EMSG2(_(e_intern2), "item_copy(UNKNOWN)");
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
}
|
}
|
||||||
--recurse;
|
--recurse;
|
||||||
@@ -24532,6 +24556,7 @@ read_viminfo_varlist(vir_T *virp, int writing)
|
|||||||
#endif
|
#endif
|
||||||
case 'D': type = VAR_DICT; break;
|
case 'D': type = VAR_DICT; break;
|
||||||
case 'L': type = VAR_LIST; break;
|
case 'L': type = VAR_LIST; break;
|
||||||
|
case 'X': type = VAR_SPECIAL; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tab = vim_strchr(tab, '\t');
|
tab = vim_strchr(tab, '\t');
|
||||||
@@ -24617,7 +24642,11 @@ write_viminfo_varlist(FILE *fp)
|
|||||||
#endif
|
#endif
|
||||||
case VAR_DICT: s = "DIC"; break;
|
case VAR_DICT: s = "DIC"; break;
|
||||||
case VAR_LIST: s = "LIS"; break;
|
case VAR_LIST: s = "LIS"; break;
|
||||||
default: continue;
|
case VAR_SPECIAL: s = "XPL"; break;
|
||||||
|
|
||||||
|
case VAR_UNKNOWN:
|
||||||
|
case VAR_FUNC:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
|
fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
|
||||||
p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
|
p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
|
||||||
|
@@ -1111,12 +1111,24 @@ typedef double float_T;
|
|||||||
typedef struct listvar_S list_T;
|
typedef struct listvar_S list_T;
|
||||||
typedef struct dictvar_S dict_T;
|
typedef struct dictvar_S dict_T;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
VAR_UNKNOWN = 0,
|
||||||
|
VAR_NUMBER, /* "v_number" is used */
|
||||||
|
VAR_STRING, /* "v_string" is used */
|
||||||
|
VAR_FUNC, /* "v_string" is function name */
|
||||||
|
VAR_LIST, /* "v_list" is used */
|
||||||
|
VAR_DICT, /* "v_dict" is used */
|
||||||
|
VAR_FLOAT, /* "v_float" is used */
|
||||||
|
VAR_SPECIAL /* "v_number" is used */
|
||||||
|
} vartype_T;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure to hold an internal variable without a name.
|
* Structure to hold an internal variable without a name.
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char v_type; /* see below: VAR_NUMBER, VAR_STRING, etc. */
|
vartype_T v_type;
|
||||||
char v_lock; /* see below: VAR_LOCKED, VAR_FIXED */
|
char v_lock; /* see below: VAR_LOCKED, VAR_FIXED */
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@@ -1130,16 +1142,6 @@ typedef struct
|
|||||||
} vval;
|
} vval;
|
||||||
} typval_T;
|
} typval_T;
|
||||||
|
|
||||||
/* Values for "v_type". */
|
|
||||||
#define VAR_UNKNOWN 0
|
|
||||||
#define VAR_NUMBER 1 /* "v_number" is used */
|
|
||||||
#define VAR_STRING 2 /* "v_string" is used */
|
|
||||||
#define VAR_FUNC 3 /* "v_string" is function name */
|
|
||||||
#define VAR_LIST 4 /* "v_list" is used */
|
|
||||||
#define VAR_DICT 5 /* "v_dict" is used */
|
|
||||||
#define VAR_FLOAT 6 /* "v_float" is used */
|
|
||||||
#define VAR_SPECIAL 7 /* "v_number" is used */
|
|
||||||
|
|
||||||
/* Values for "dv_scope". */
|
/* Values for "dv_scope". */
|
||||||
#define VAR_SCOPE 1 /* a:, v:, s:, etc. scope dictionaries */
|
#define VAR_SCOPE 1 /* a:, v:, s:, etc. scope dictionaries */
|
||||||
#define VAR_DEF_SCOPE 2 /* l:, g: scope dictionaries: here funcrefs are not
|
#define VAR_DEF_SCOPE 2 /* l:, g: scope dictionaries: here funcrefs are not
|
||||||
|
@@ -742,6 +742,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1267,
|
||||||
/**/
|
/**/
|
||||||
1266,
|
1266,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user