summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-02-06 18:09:59 +0100
committerBram Moolenaar <Bram@vim.org>2016-02-06 18:09:59 +0100
commita03f23351588f04276469cd7742b7ec655bb604b (patch)
tree449e754ee515453f09d8dd85fd381cd064551fcf
parentab9fc7e0cf22bcee119b62d3433cac60f405e645 (diff)
downloadvim-git-a03f23351588f04276469cd7742b7ec655bb604b.tar.gz
patch 7.4.1267v7.4.1267
Problem: Easy to miss handling all types of variables. Solution: Change the variable type into an enum.
-rw-r--r--src/eval.c215
-rw-r--r--src/structs.h24
-rw-r--r--src/version.c2
3 files changed, 137 insertions, 104 deletions
diff --git a/src/eval.c b/src/eval.c
index 33ec495e8..7ce739ce7 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3065,6 +3065,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
case VAR_DICT:
case VAR_FUNC:
case VAR_SPECIAL:
+ case VAR_UNKNOWN:
break;
case VAR_LIST:
@@ -3837,6 +3838,14 @@ item_lock(typval_T *tv, int deep, int lock)
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:
if ((l = tv->vval.v_list) != NULL)
{
@@ -5317,23 +5326,32 @@ eval_index(
char_u *s;
char_u *key = NULL;
- if (rettv->v_type == VAR_FUNC)
+ switch (rettv->v_type)
{
- if (verbose)
- EMSG(_("E695: Cannot index a Funcref"));
- return FAIL;
- }
+ case VAR_FUNC:
+ if (verbose)
+ EMSG(_("E695: Cannot index a Funcref"));
+ return FAIL;
+ case VAR_FLOAT:
#ifdef FEAT_FLOAT
- else if (rettv->v_type == VAR_FLOAT)
- {
- if (verbose)
- EMSG(_(e_float_as_string));
- return FAIL;
- }
+ if (verbose)
+ EMSG(_(e_float_as_string));
+ return FAIL;
#endif
- else if (rettv->v_type == VAR_SPECIAL)
- {
- return FAIL;
+ case VAR_SPECIAL:
+ if (verbose)
+ 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);
@@ -5428,6 +5446,12 @@ eval_index(
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_STRING:
s = get_tv_string(rettv);
@@ -6143,6 +6167,9 @@ tv_equal(
switch (tv1->v_type)
{
+ case VAR_UNKNOWN:
+ break;
+
case VAR_LIST:
++recursive_cnt;
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;
}
- EMSG2(_(e_intern2), "tv_equal()");
- return TRUE;
+ /* VAR_UNKNOWN can be the result of a invalid expression, let's say it
+ * does not equal anything, not even itself. */
+ return FALSE;
}
/*
@@ -7047,59 +7075,56 @@ set_ref_in_item(
list_T *ll;
int abort = FALSE;
- switch (tv->v_type)
+ if (tv->v_type == VAR_DICT)
{
- case VAR_DICT:
- dd = tv->vval.v_dict;
- if (dd != NULL && dd->dv_copyID != copyID)
+ dd = tv->vval.v_dict;
+ 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. */
- dd->dv_copyID = copyID;
- if (ht_stack == NULL)
- {
- abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
- }
+ abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
+ }
+ else
+ {
+ ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T));
+ if (newitem == NULL)
+ abort = TRUE;
else
{
- ht_stack_T *newitem = (ht_stack_T*)malloc(
- sizeof(ht_stack_T));
- if (newitem == NULL)
- abort = TRUE;
- else
- {
- newitem->ht = &dd->dv_hashtab;
- newitem->prev = *ht_stack;
- *ht_stack = newitem;
- }
+ newitem->ht = &dd->dv_hashtab;
+ newitem->prev = *ht_stack;
+ *ht_stack = newitem;
}
}
- break;
-
- case VAR_LIST:
- ll = tv->vval.v_list;
- if (ll != NULL && ll->lv_copyID != copyID)
+ }
+ }
+ else if (tv->v_type == VAR_LIST)
+ {
+ 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. */
- ll->lv_copyID = copyID;
- if (list_stack == NULL)
- {
- abort = set_ref_in_list(ll, copyID, ht_stack);
- }
+ abort = set_ref_in_list(ll, copyID, ht_stack);
+ }
+ else
+ {
+ list_stack_T *newitem = (list_stack_T*)malloc(
+ sizeof(list_stack_T));
+ if (newitem == NULL)
+ abort = TRUE;
else
{
- list_stack_T *newitem = (list_stack_T*)malloc(
- sizeof(list_stack_T));
- if (newitem == NULL)
- abort = TRUE;
- else
- {
- newitem->list = ll;
- newitem->prev = *list_stack;
- *list_stack = newitem;
- }
+ newitem->list = ll;
+ newitem->prev = *list_stack;
+ *list_stack = newitem;
}
}
- break;
+ }
}
return abort;
}
@@ -7763,6 +7788,7 @@ echo_string(
case VAR_STRING:
case VAR_NUMBER:
+ case VAR_UNKNOWN:
*tofree = NULL;
r = get_tv_string_buf(tv, numbuf);
break;
@@ -7779,10 +7805,6 @@ echo_string(
*tofree = NULL;
r = (char_u *)get_var_special_name(tv->vval.v_number);
break;
-
- default:
- EMSG2(_(e_intern2), "echo_string()");
- *tofree = NULL;
}
if (--recurse == 0)
@@ -7822,9 +7844,8 @@ tv2string(
case VAR_LIST:
case VAR_DICT:
case VAR_SPECIAL:
+ case VAR_UNKNOWN:
break;
- default:
- EMSG2(_(e_intern2), "tv2string()");
}
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;
break;
- default:
- EMSG2(_(e_intern2), "f_empty()");
- n = 0;
+ case VAR_UNKNOWN:
+ EMSG2(_(e_intern2), "f_empty(UNKNOWN)");
+ n = TRUE;
+ break;
}
rettv->vval.v_number = n;
@@ -14266,7 +14288,10 @@ f_len(typval_T *argvars, typval_T *rettv)
case VAR_DICT:
rettv->vval.v_number = dict_len(argvars[0].vval.v_dict);
break;
- default:
+ case VAR_UNKNOWN:
+ case VAR_SPECIAL:
+ case VAR_FLOAT:
+ case VAR_FUNC:
EMSG(_("E701: Invalid type for len()"));
break;
}
@@ -19624,13 +19649,16 @@ f_type(typval_T *argvars, typval_T *rettv)
case VAR_FLOAT: n = 5; break;
#endif
case VAR_SPECIAL:
- if (argvars[0].vval.v_number == VVAL_FALSE
- || argvars[0].vval.v_number == VVAL_TRUE)
- n = 6;
- else
- n = 7;
- break;
- default: EMSG2(_(e_intern2), "f_type()"); n = 0; break;
+ if (argvars[0].vval.v_number == VVAL_FALSE
+ || argvars[0].vval.v_number == VVAL_TRUE)
+ n = 6;
+ else
+ n = 7;
+ break;
+ case VAR_UNKNOWN:
+ EMSG2(_(e_intern2), "f_type(UNKNOWN)");
+ n = -1;
+ break;
}
rettv->vval.v_number = n;
}
@@ -21000,9 +21028,6 @@ free_tv(typval_T *varp)
case VAR_UNKNOWN:
case VAR_SPECIAL:
break;
- default:
- EMSG2(_(e_intern2), "free_tv()");
- break;
}
vim_free(varp);
}
@@ -21044,8 +21069,6 @@ clear_tv(typval_T *varp)
#endif
case VAR_UNKNOWN:
break;
- default:
- EMSG2(_(e_intern2), "clear_tv()");
}
varp->v_lock = 0;
}
@@ -21108,8 +21131,8 @@ get_tv_number_chk(typval_T *varp, int *denote)
case VAR_SPECIAL:
return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
break;
- default:
- EMSG2(_(e_intern2), "get_tv_number()");
+ case VAR_UNKNOWN:
+ EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)");
break;
}
if (denote == NULL) /* useful for values that must be unsigned */
@@ -21130,7 +21153,6 @@ get_tv_float(typval_T *varp)
#ifdef FEAT_FLOAT
case VAR_FLOAT:
return varp->vval.v_float;
- break;
#endif
case VAR_FUNC:
EMSG(_("E891: Using a Funcref as a Float"));
@@ -21144,8 +21166,11 @@ get_tv_float(typval_T *varp)
case VAR_DICT:
EMSG(_("E894: Using a Dictionary as a Float"));
break;
- default:
- EMSG2(_(e_intern2), "get_tv_float()");
+ case VAR_SPECIAL:
+ EMSG(_("E907: Using a special value as a Float"));
+ break;
+ case VAR_UNKNOWN:
+ EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)");
break;
}
return 0;
@@ -21256,9 +21281,8 @@ get_tv_string_buf_chk(typval_T *varp, char_u *buf)
case VAR_SPECIAL:
STRCPY(buf, get_var_special_name(varp->vval.v_number));
return buf;
-
- default:
- EMSG2(_(e_intern2), "get_tv_string_buf()");
+ case VAR_UNKNOWN:
+ EMSG(_("E908: using an invalid value as a String"));
break;
}
return NULL;
@@ -21910,8 +21934,8 @@ copy_tv(typval_T *from, typval_T *to)
++to->vval.v_dict->dv_refcount;
}
break;
- default:
- EMSG2(_(e_intern2), "copy_tv()");
+ case VAR_UNKNOWN:
+ EMSG2(_(e_intern2), "copy_tv(UNKNOWN)");
break;
}
}
@@ -21983,8 +22007,8 @@ item_copy(
if (to->vval.v_dict == NULL)
ret = FAIL;
break;
- default:
- EMSG2(_(e_intern2), "item_copy()");
+ case VAR_UNKNOWN:
+ EMSG2(_(e_intern2), "item_copy(UNKNOWN)");
ret = FAIL;
}
--recurse;
@@ -24532,6 +24556,7 @@ read_viminfo_varlist(vir_T *virp, int writing)
#endif
case 'D': type = VAR_DICT; break;
case 'L': type = VAR_LIST; break;
+ case 'X': type = VAR_SPECIAL; break;
}
tab = vim_strchr(tab, '\t');
@@ -24617,7 +24642,11 @@ write_viminfo_varlist(FILE *fp)
#endif
case VAR_DICT: s = "DIC"; 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);
p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
diff --git a/src/structs.h b/src/structs.h
index 26f403f2a..d10547acf 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1111,12 +1111,24 @@ typedef double float_T;
typedef struct listvar_S list_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.
*/
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 */
union
{
@@ -1130,16 +1142,6 @@ typedef struct
} vval;
} 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". */
#define VAR_SCOPE 1 /* a:, v:, s:, etc. scope dictionaries */
#define VAR_DEF_SCOPE 2 /* l:, g: scope dictionaries: here funcrefs are not
diff --git a/src/version.c b/src/version.c
index 51f0503c6..47f45deef 100644
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1267,
+/**/
1266,
/**/
1265,