Skip to content

Commit a03f233

Browse files
committed
patch 7.4.1267
Problem: Easy to miss handling all types of variables. Solution: Change the variable type into an enum.
1 parent ab9fc7e commit a03f233

3 files changed

Lines changed: 137 additions & 104 deletions

File tree

src/eval.c

Lines changed: 122 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -3065,6 +3065,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
30653065
case VAR_DICT:
30663066
case VAR_FUNC:
30673067
case VAR_SPECIAL:
3068+
case VAR_UNKNOWN:
30683069
break;
30693070

30703071
case VAR_LIST:
@@ -3837,6 +3838,14 @@ item_lock(typval_T *tv, int deep, int lock)
38373838

38383839
switch (tv->v_type)
38393840
{
3841+
case VAR_UNKNOWN:
3842+
case VAR_NUMBER:
3843+
case VAR_STRING:
3844+
case VAR_FUNC:
3845+
case VAR_FLOAT:
3846+
case VAR_SPECIAL:
3847+
break;
3848+
38403849
case VAR_LIST:
38413850
if ((l = tv->vval.v_list) != NULL)
38423851
{
@@ -5317,23 +5326,32 @@ eval_index(
53175326
char_u *s;
53185327
char_u *key = NULL;
53195328

5320-
if (rettv->v_type == VAR_FUNC)
5329+
switch (rettv->v_type)
53215330
{
5322-
if (verbose)
5323-
EMSG(_("E695: Cannot index a Funcref"));
5324-
return FAIL;
5325-
}
5331+
case VAR_FUNC:
5332+
if (verbose)
5333+
EMSG(_("E695: Cannot index a Funcref"));
5334+
return FAIL;
5335+
case VAR_FLOAT:
53265336
#ifdef FEAT_FLOAT
5327-
else if (rettv->v_type == VAR_FLOAT)
5328-
{
5329-
if (verbose)
5330-
EMSG(_(e_float_as_string));
5331-
return FAIL;
5332-
}
5337+
if (verbose)
5338+
EMSG(_(e_float_as_string));
5339+
return FAIL;
53335340
#endif
5334-
else if (rettv->v_type == VAR_SPECIAL)
5335-
{
5336-
return FAIL;
5341+
case VAR_SPECIAL:
5342+
if (verbose)
5343+
EMSG(_("E909: Cannot index a special variable"));
5344+
return FAIL;
5345+
case VAR_UNKNOWN:
5346+
if (evaluate)
5347+
return FAIL;
5348+
/* FALLTHROUGH */
5349+
5350+
case VAR_STRING:
5351+
case VAR_NUMBER:
5352+
case VAR_LIST:
5353+
case VAR_DICT:
5354+
break;
53375355
}
53385356

53395357
init_tv(&var1);
@@ -5428,6 +5446,12 @@ eval_index(
54285446

54295447
switch (rettv->v_type)
54305448
{
5449+
case VAR_SPECIAL:
5450+
case VAR_FUNC:
5451+
case VAR_FLOAT:
5452+
case VAR_UNKNOWN:
5453+
break; /* not evaluating, skipping over subscript */
5454+
54315455
case VAR_NUMBER:
54325456
case VAR_STRING:
54335457
s = get_tv_string(rettv);
@@ -6143,6 +6167,9 @@ tv_equal(
61436167

61446168
switch (tv1->v_type)
61456169
{
6170+
case VAR_UNKNOWN:
6171+
break;
6172+
61466173
case VAR_LIST:
61476174
++recursive_cnt;
61486175
r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
@@ -6177,8 +6204,9 @@ tv_equal(
61776204
return tv1->vval.v_number == tv2->vval.v_number;
61786205
}
61796206

6180-
EMSG2(_(e_intern2), "tv_equal()");
6181-
return TRUE;
6207+
/* VAR_UNKNOWN can be the result of a invalid expression, let's say it
6208+
* does not equal anything, not even itself. */
6209+
return FALSE;
61826210
}
61836211

61846212
/*
@@ -7047,59 +7075,56 @@ set_ref_in_item(
70477075
list_T *ll;
70487076
int abort = FALSE;
70497077

7050-
switch (tv->v_type)
7078+
if (tv->v_type == VAR_DICT)
70517079
{
7052-
case VAR_DICT:
7053-
dd = tv->vval.v_dict;
7054-
if (dd != NULL && dd->dv_copyID != copyID)
7080+
dd = tv->vval.v_dict;
7081+
if (dd != NULL && dd->dv_copyID != copyID)
7082+
{
7083+
/* Didn't see this dict yet. */
7084+
dd->dv_copyID = copyID;
7085+
if (ht_stack == NULL)
70557086
{
7056-
/* Didn't see this dict yet. */
7057-
dd->dv_copyID = copyID;
7058-
if (ht_stack == NULL)
7059-
{
7060-
abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
7061-
}
7087+
abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack);
7088+
}
7089+
else
7090+
{
7091+
ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T));
7092+
if (newitem == NULL)
7093+
abort = TRUE;
70627094
else
70637095
{
7064-
ht_stack_T *newitem = (ht_stack_T*)malloc(
7065-
sizeof(ht_stack_T));
7066-
if (newitem == NULL)
7067-
abort = TRUE;
7068-
else
7069-
{
7070-
newitem->ht = &dd->dv_hashtab;
7071-
newitem->prev = *ht_stack;
7072-
*ht_stack = newitem;
7073-
}
7096+
newitem->ht = &dd->dv_hashtab;
7097+
newitem->prev = *ht_stack;
7098+
*ht_stack = newitem;
70747099
}
70757100
}
7076-
break;
7077-
7078-
case VAR_LIST:
7079-
ll = tv->vval.v_list;
7080-
if (ll != NULL && ll->lv_copyID != copyID)
7101+
}
7102+
}
7103+
else if (tv->v_type == VAR_LIST)
7104+
{
7105+
ll = tv->vval.v_list;
7106+
if (ll != NULL && ll->lv_copyID != copyID)
7107+
{
7108+
/* Didn't see this list yet. */
7109+
ll->lv_copyID = copyID;
7110+
if (list_stack == NULL)
70817111
{
7082-
/* Didn't see this list yet. */
7083-
ll->lv_copyID = copyID;
7084-
if (list_stack == NULL)
7085-
{
7086-
abort = set_ref_in_list(ll, copyID, ht_stack);
7087-
}
7112+
abort = set_ref_in_list(ll, copyID, ht_stack);
7113+
}
7114+
else
7115+
{
7116+
list_stack_T *newitem = (list_stack_T*)malloc(
7117+
sizeof(list_stack_T));
7118+
if (newitem == NULL)
7119+
abort = TRUE;
70887120
else
70897121
{
7090-
list_stack_T *newitem = (list_stack_T*)malloc(
7091-
sizeof(list_stack_T));
7092-
if (newitem == NULL)
7093-
abort = TRUE;
7094-
else
7095-
{
7096-
newitem->list = ll;
7097-
newitem->prev = *list_stack;
7098-
*list_stack = newitem;
7099-
}
7122+
newitem->list = ll;
7123+
newitem->prev = *list_stack;
7124+
*list_stack = newitem;
71007125
}
71017126
}
7102-
break;
7127+
}
71037128
}
71047129
return abort;
71057130
}
@@ -7763,6 +7788,7 @@ echo_string(
77637788

77647789
case VAR_STRING:
77657790
case VAR_NUMBER:
7791+
case VAR_UNKNOWN:
77667792
*tofree = NULL;
77677793
r = get_tv_string_buf(tv, numbuf);
77687794
break;
@@ -7779,10 +7805,6 @@ echo_string(
77797805
*tofree = NULL;
77807806
r = (char_u *)get_var_special_name(tv->vval.v_number);
77817807
break;
7782-
7783-
default:
7784-
EMSG2(_(e_intern2), "echo_string()");
7785-
*tofree = NULL;
77867808
}
77877809

77887810
if (--recurse == 0)
@@ -7822,9 +7844,8 @@ tv2string(
78227844
case VAR_LIST:
78237845
case VAR_DICT:
78247846
case VAR_SPECIAL:
7847+
case VAR_UNKNOWN:
78257848
break;
7826-
default:
7827-
EMSG2(_(e_intern2), "tv2string()");
78287849
}
78297850
return echo_string(tv, tofree, numbuf, copyID);
78307851
}
@@ -10528,9 +10549,10 @@ f_empty(typval_T *argvars, typval_T *rettv)
1052810549
n = argvars[0].vval.v_number != VVAL_TRUE;
1052910550
break;
1053010551

10531-
default:
10532-
EMSG2(_(e_intern2), "f_empty()");
10533-
n = 0;
10552+
case VAR_UNKNOWN:
10553+
EMSG2(_(e_intern2), "f_empty(UNKNOWN)");
10554+
n = TRUE;
10555+
break;
1053410556
}
1053510557

1053610558
rettv->vval.v_number = n;
@@ -14266,7 +14288,10 @@ f_len(typval_T *argvars, typval_T *rettv)
1426614288
case VAR_DICT:
1426714289
rettv->vval.v_number = dict_len(argvars[0].vval.v_dict);
1426814290
break;
14269-
default:
14291+
case VAR_UNKNOWN:
14292+
case VAR_SPECIAL:
14293+
case VAR_FLOAT:
14294+
case VAR_FUNC:
1427014295
EMSG(_("E701: Invalid type for len()"));
1427114296
break;
1427214297
}
@@ -19624,13 +19649,16 @@ f_type(typval_T *argvars, typval_T *rettv)
1962419649
case VAR_FLOAT: n = 5; break;
1962519650
#endif
1962619651
case VAR_SPECIAL:
19627-
if (argvars[0].vval.v_number == VVAL_FALSE
19628-
|| argvars[0].vval.v_number == VVAL_TRUE)
19629-
n = 6;
19630-
else
19631-
n = 7;
19632-
break;
19633-
default: EMSG2(_(e_intern2), "f_type()"); n = 0; break;
19652+
if (argvars[0].vval.v_number == VVAL_FALSE
19653+
|| argvars[0].vval.v_number == VVAL_TRUE)
19654+
n = 6;
19655+
else
19656+
n = 7;
19657+
break;
19658+
case VAR_UNKNOWN:
19659+
EMSG2(_(e_intern2), "f_type(UNKNOWN)");
19660+
n = -1;
19661+
break;
1963419662
}
1963519663
rettv->vval.v_number = n;
1963619664
}
@@ -21000,9 +21028,6 @@ free_tv(typval_T *varp)
2100021028
case VAR_UNKNOWN:
2100121029
case VAR_SPECIAL:
2100221030
break;
21003-
default:
21004-
EMSG2(_(e_intern2), "free_tv()");
21005-
break;
2100621031
}
2100721032
vim_free(varp);
2100821033
}
@@ -21044,8 +21069,6 @@ clear_tv(typval_T *varp)
2104421069
#endif
2104521070
case VAR_UNKNOWN:
2104621071
break;
21047-
default:
21048-
EMSG2(_(e_intern2), "clear_tv()");
2104921072
}
2105021073
varp->v_lock = 0;
2105121074
}
@@ -21108,8 +21131,8 @@ get_tv_number_chk(typval_T *varp, int *denote)
2110821131
case VAR_SPECIAL:
2110921132
return varp->vval.v_number == VVAL_TRUE ? 1 : 0;
2111021133
break;
21111-
default:
21112-
EMSG2(_(e_intern2), "get_tv_number()");
21134+
case VAR_UNKNOWN:
21135+
EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)");
2111321136
break;
2111421137
}
2111521138
if (denote == NULL) /* useful for values that must be unsigned */
@@ -21130,7 +21153,6 @@ get_tv_float(typval_T *varp)
2113021153
#ifdef FEAT_FLOAT
2113121154
case VAR_FLOAT:
2113221155
return varp->vval.v_float;
21133-
break;
2113421156
#endif
2113521157
case VAR_FUNC:
2113621158
EMSG(_("E891: Using a Funcref as a Float"));
@@ -21144,8 +21166,11 @@ get_tv_float(typval_T *varp)
2114421166
case VAR_DICT:
2114521167
EMSG(_("E894: Using a Dictionary as a Float"));
2114621168
break;
21147-
default:
21148-
EMSG2(_(e_intern2), "get_tv_float()");
21169+
case VAR_SPECIAL:
21170+
EMSG(_("E907: Using a special value as a Float"));
21171+
break;
21172+
case VAR_UNKNOWN:
21173+
EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)");
2114921174
break;
2115021175
}
2115121176
return 0;
@@ -21256,9 +21281,8 @@ get_tv_string_buf_chk(typval_T *varp, char_u *buf)
2125621281
case VAR_SPECIAL:
2125721282
STRCPY(buf, get_var_special_name(varp->vval.v_number));
2125821283
return buf;
21259-
21260-
default:
21261-
EMSG2(_(e_intern2), "get_tv_string_buf()");
21284+
case VAR_UNKNOWN:
21285+
EMSG(_("E908: using an invalid value as a String"));
2126221286
break;
2126321287
}
2126421288
return NULL;
@@ -21910,8 +21934,8 @@ copy_tv(typval_T *from, typval_T *to)
2191021934
++to->vval.v_dict->dv_refcount;
2191121935
}
2191221936
break;
21913-
default:
21914-
EMSG2(_(e_intern2), "copy_tv()");
21937+
case VAR_UNKNOWN:
21938+
EMSG2(_(e_intern2), "copy_tv(UNKNOWN)");
2191521939
break;
2191621940
}
2191721941
}
@@ -21983,8 +22007,8 @@ item_copy(
2198322007
if (to->vval.v_dict == NULL)
2198422008
ret = FAIL;
2198522009
break;
21986-
default:
21987-
EMSG2(_(e_intern2), "item_copy()");
22010+
case VAR_UNKNOWN:
22011+
EMSG2(_(e_intern2), "item_copy(UNKNOWN)");
2198822012
ret = FAIL;
2198922013
}
2199022014
--recurse;
@@ -24532,6 +24556,7 @@ read_viminfo_varlist(vir_T *virp, int writing)
2453224556
#endif
2453324557
case 'D': type = VAR_DICT; break;
2453424558
case 'L': type = VAR_LIST; break;
24559+
case 'X': type = VAR_SPECIAL; break;
2453524560
}
2453624561

2453724562
tab = vim_strchr(tab, '\t');
@@ -24617,7 +24642,11 @@ write_viminfo_varlist(FILE *fp)
2461724642
#endif
2461824643
case VAR_DICT: s = "DIC"; break;
2461924644
case VAR_LIST: s = "LIS"; break;
24620-
default: continue;
24645+
case VAR_SPECIAL: s = "XPL"; break;
24646+
24647+
case VAR_UNKNOWN:
24648+
case VAR_FUNC:
24649+
continue;
2462124650
}
2462224651
fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
2462324652
p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);

0 commit comments

Comments
 (0)