# HG changeset patch # User Christian Brabandt # Date 1454778904 -3600 # Node ID e875f0fbd9c0f6098ff044e7160c121022b06ce7 # Parent 5d117679edcda12c7f45769837a01ebb1b343a7e commit https://github.com/vim/vim/commit/a03f23351588f04276469cd7742b7ec655bb604b Author: Bram Moolenaar Date: Sat Feb 6 18:09:59 2016 +0100 patch 7.4.1267 Problem: Easy to miss handling all types of variables. Solution: Change the variable type into an enum. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -3065,6 +3065,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char 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 lo 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) - { - if (verbose) - EMSG(_("E695: Cannot index a Funcref")); - return FAIL; - } -#ifdef FEAT_FLOAT - else if (rettv->v_type == VAR_FLOAT) - { - if (verbose) - EMSG(_(e_float_as_string)); - return FAIL; - } -#endif - else if (rettv->v_type == VAR_SPECIAL) - { - return FAIL; + switch (rettv->v_type) + { + case VAR_FUNC: + if (verbose) + EMSG(_("E695: Cannot index a Funcref")); + return FAIL; + case VAR_FLOAT: +#ifdef FEAT_FLOAT + if (verbose) + EMSG(_(e_float_as_string)); + return FAIL; +#endif + 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) - { - case VAR_DICT: - 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) - { - 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 - { - 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) - { - /* Didn't see this list yet. */ - ll->lv_copyID = copyID; - if (list_stack == NULL) - { - abort = set_ref_in_list(ll, copyID, ht_stack); - } - else - { - list_stack_T *newitem = (list_stack_T*)malloc( + if (tv->v_type == VAR_DICT) + { + 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) + { + 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 + { + newitem->ht = &dd->dv_hashtab; + newitem->prev = *ht_stack; + *ht_stack = newitem; + } + } + } + } + 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) + { + 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 - { - newitem->list = ll; - newitem->prev = *list_stack; - *list_stack = newitem; - } - } - } - break; + if (newitem == NULL) + abort = TRUE; + else + { + newitem->list = ll; + newitem->prev = *list_stack; + *list_stack = newitem; + } + } + } } 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: - break; - default: - EMSG2(_(e_intern2), "tv2string()"); + case VAR_UNKNOWN: + break; } return echo_string(tv, tofree, numbuf, copyID); } @@ -10528,9 +10549,10 @@ f_empty(typval_T *argvars, typval_T *ret 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 *rett 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 *d 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, ch 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 wr #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 --- 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 --- 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,