To: vim_dev@googlegroups.com Subject: Patch 7.4.1267 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1267 Problem: Easy to miss handling all types of variables. Solution: Change the variable type into an enum. Files: src/structs.h, src/eval.c *** ../vim-7.4.1266/src/structs.h 2016-02-02 18:19:52.798743887 +0100 --- src/structs.h 2016-02-06 16:17:00.238321359 +0100 *************** *** 1111,1122 **** typedef struct listvar_S list_T; typedef struct dictvar_S dict_T; /* * Structure to hold an internal variable without a name. */ typedef struct { ! char v_type; /* see below: VAR_NUMBER, VAR_STRING, etc. */ char v_lock; /* see below: VAR_LOCKED, VAR_FIXED */ union { --- 1111,1134 ---- 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 { ! vartype_T v_type; char v_lock; /* see below: VAR_LOCKED, VAR_FIXED */ union { *************** *** 1130,1145 **** } 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 --- 1142,1147 ---- *** ../vim-7.4.1266/src/eval.c 2016-02-05 22:49:50.681170583 +0100 --- src/eval.c 2016-02-06 17:39:52.430587000 +0100 *************** *** 3065,3070 **** --- 3065,3071 ---- case VAR_DICT: case VAR_FUNC: case VAR_SPECIAL: + case VAR_UNKNOWN: break; case VAR_LIST: *************** *** 3837,3842 **** --- 3838,3851 ---- 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,5339 **** 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; } init_tv(&var1); --- 5326,5357 ---- char_u *s; char_u *key = NULL; ! 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,5433 **** --- 5446,5457 ---- 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,6148 **** --- 6167,6175 ---- 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,6184 **** return tv1->vval.v_number == tv2->vval.v_number; } ! EMSG2(_(e_intern2), "tv_equal()"); ! return TRUE; } /* --- 6204,6212 ---- return tv1->vval.v_number == tv2->vval.v_number; } ! /* VAR_UNKNOWN can be the result of a invalid expression, let's say it ! * does not equal anything, not even itself. */ ! return FALSE; } /* *************** *** 7047,7105 **** 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( ! sizeof(list_stack_T)); ! if (newitem == NULL) ! abort = TRUE; ! else ! { ! newitem->list = ll; ! newitem->prev = *list_stack; ! *list_stack = newitem; ! } } } ! break; } return abort; } --- 7075,7130 ---- list_T *ll; int abort = FALSE; ! 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; } } ! } } return abort; } *************** *** 7763,7768 **** --- 7788,7794 ---- case VAR_STRING: case VAR_NUMBER: + case VAR_UNKNOWN: *tofree = NULL; r = get_tv_string_buf(tv, numbuf); break; *************** *** 7779,7788 **** *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) --- 7805,7810 ---- *************** *** 7822,7830 **** case VAR_LIST: case VAR_DICT: case VAR_SPECIAL: break; - default: - EMSG2(_(e_intern2), "tv2string()"); } return echo_string(tv, tofree, numbuf, copyID); } --- 7844,7851 ---- case VAR_LIST: case VAR_DICT: case VAR_SPECIAL: + case VAR_UNKNOWN: break; } return echo_string(tv, tofree, numbuf, copyID); } *************** *** 10528,10536 **** n = argvars[0].vval.v_number != VVAL_TRUE; break; ! default: ! EMSG2(_(e_intern2), "f_empty()"); ! n = 0; } rettv->vval.v_number = n; --- 10549,10558 ---- n = argvars[0].vval.v_number != VVAL_TRUE; break; ! case VAR_UNKNOWN: ! EMSG2(_(e_intern2), "f_empty(UNKNOWN)"); ! n = TRUE; ! break; } rettv->vval.v_number = n; *************** *** 14266,14272 **** case VAR_DICT: rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); break; ! default: EMSG(_("E701: Invalid type for len()")); break; } --- 14288,14297 ---- case VAR_DICT: rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); break; ! case VAR_UNKNOWN: ! case VAR_SPECIAL: ! case VAR_FLOAT: ! case VAR_FUNC: EMSG(_("E701: Invalid type for len()")); break; } *************** *** 19624,19636 **** 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; } rettv->vval.v_number = n; } --- 19649,19664 ---- 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; ! case VAR_UNKNOWN: ! EMSG2(_(e_intern2), "f_type(UNKNOWN)"); ! n = -1; ! break; } rettv->vval.v_number = n; } *************** *** 21000,21008 **** case VAR_UNKNOWN: case VAR_SPECIAL: break; - default: - EMSG2(_(e_intern2), "free_tv()"); - break; } vim_free(varp); } --- 21028,21033 ---- *************** *** 21044,21051 **** #endif case VAR_UNKNOWN: break; - default: - EMSG2(_(e_intern2), "clear_tv()"); } varp->v_lock = 0; } --- 21069,21074 ---- *************** *** 21108,21115 **** case VAR_SPECIAL: return varp->vval.v_number == VVAL_TRUE ? 1 : 0; break; ! default: ! EMSG2(_(e_intern2), "get_tv_number()"); break; } if (denote == NULL) /* useful for values that must be unsigned */ --- 21131,21138 ---- case VAR_SPECIAL: return varp->vval.v_number == VVAL_TRUE ? 1 : 0; break; ! case VAR_UNKNOWN: ! EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)"); break; } if (denote == NULL) /* useful for values that must be unsigned */ *************** *** 21130,21136 **** #ifdef FEAT_FLOAT case VAR_FLOAT: return varp->vval.v_float; - break; #endif case VAR_FUNC: EMSG(_("E891: Using a Funcref as a Float")); --- 21153,21158 ---- *************** *** 21144,21151 **** case VAR_DICT: EMSG(_("E894: Using a Dictionary as a Float")); break; ! default: ! EMSG2(_(e_intern2), "get_tv_float()"); break; } return 0; --- 21166,21176 ---- case VAR_DICT: EMSG(_("E894: Using a Dictionary as a Float")); break; ! 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,21264 **** case VAR_SPECIAL: STRCPY(buf, get_var_special_name(varp->vval.v_number)); return buf; ! ! default: ! EMSG2(_(e_intern2), "get_tv_string_buf()"); break; } return NULL; --- 21281,21288 ---- case VAR_SPECIAL: STRCPY(buf, get_var_special_name(varp->vval.v_number)); return buf; ! case VAR_UNKNOWN: ! EMSG(_("E908: using an invalid value as a String")); break; } return NULL; *************** *** 21910,21917 **** ++to->vval.v_dict->dv_refcount; } break; ! default: ! EMSG2(_(e_intern2), "copy_tv()"); break; } } --- 21934,21941 ---- ++to->vval.v_dict->dv_refcount; } break; ! case VAR_UNKNOWN: ! EMSG2(_(e_intern2), "copy_tv(UNKNOWN)"); break; } } *************** *** 21983,21990 **** if (to->vval.v_dict == NULL) ret = FAIL; break; ! default: ! EMSG2(_(e_intern2), "item_copy()"); ret = FAIL; } --recurse; --- 22007,22014 ---- if (to->vval.v_dict == NULL) ret = FAIL; break; ! case VAR_UNKNOWN: ! EMSG2(_(e_intern2), "item_copy(UNKNOWN)"); ret = FAIL; } --recurse; *************** *** 24532,24537 **** --- 24556,24562 ---- #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,24623 **** #endif case VAR_DICT: s = "DIC"; break; case VAR_LIST: s = "LIS"; break; ! default: continue; } fprintf(fp, "!%s\t%s\t", this_var->di_key, s); p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); --- 24642,24652 ---- #endif case VAR_DICT: s = "DIC"; break; case VAR_LIST: s = "LIS"; break; ! 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); *** ../vim-7.4.1266/src/version.c 2016-02-06 15:29:34.784012360 +0100 --- src/version.c 2016-02-06 16:43:23.481833271 +0100 *************** *** 744,745 **** --- 744,747 ---- { /* Add new patch number below this line */ + /**/ + 1267, /**/ -- hundred-and-one symptoms of being an internet addict: 155. You forget to eat because you're too busy surfing the net. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///