Mercurial > vim
comparison src/eval.c @ 7943:e875f0fbd9c0 v7.4.1267
commit https://github.com/vim/vim/commit/a03f23351588f04276469cd7742b7ec655bb604b
Author: Bram Moolenaar <Bram@vim.org>
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.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 06 Feb 2016 18:15:04 +0100 |
parents | 2e905dfc6999 |
children | 03e716299680 |
comparison
equal
deleted
inserted
replaced
7942:5d117679edcd | 7943:e875f0fbd9c0 |
---|---|
3063 switch (tv1->v_type) | 3063 switch (tv1->v_type) |
3064 { | 3064 { |
3065 case VAR_DICT: | 3065 case VAR_DICT: |
3066 case VAR_FUNC: | 3066 case VAR_FUNC: |
3067 case VAR_SPECIAL: | 3067 case VAR_SPECIAL: |
3068 case VAR_UNKNOWN: | |
3068 break; | 3069 break; |
3069 | 3070 |
3070 case VAR_LIST: | 3071 case VAR_LIST: |
3071 if (*op != '+' || tv2->v_type != VAR_LIST) | 3072 if (*op != '+' || tv2->v_type != VAR_LIST) |
3072 break; | 3073 break; |
3835 else | 3836 else |
3836 tv->v_lock &= ~VAR_LOCKED; | 3837 tv->v_lock &= ~VAR_LOCKED; |
3837 | 3838 |
3838 switch (tv->v_type) | 3839 switch (tv->v_type) |
3839 { | 3840 { |
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 | |
3840 case VAR_LIST: | 3849 case VAR_LIST: |
3841 if ((l = tv->vval.v_list) != NULL) | 3850 if ((l = tv->vval.v_list) != NULL) |
3842 { | 3851 { |
3843 if (lock) | 3852 if (lock) |
3844 l->lv_lock |= VAR_LOCKED; | 3853 l->lv_lock |= VAR_LOCKED; |
5315 long len = -1; | 5324 long len = -1; |
5316 int range = FALSE; | 5325 int range = FALSE; |
5317 char_u *s; | 5326 char_u *s; |
5318 char_u *key = NULL; | 5327 char_u *key = NULL; |
5319 | 5328 |
5320 if (rettv->v_type == VAR_FUNC) | 5329 switch (rettv->v_type) |
5321 { | 5330 { |
5322 if (verbose) | 5331 case VAR_FUNC: |
5323 EMSG(_("E695: Cannot index a Funcref")); | 5332 if (verbose) |
5324 return FAIL; | 5333 EMSG(_("E695: Cannot index a Funcref")); |
5325 } | 5334 return FAIL; |
5335 case VAR_FLOAT: | |
5326 #ifdef FEAT_FLOAT | 5336 #ifdef FEAT_FLOAT |
5327 else if (rettv->v_type == VAR_FLOAT) | 5337 if (verbose) |
5328 { | 5338 EMSG(_(e_float_as_string)); |
5329 if (verbose) | 5339 return FAIL; |
5330 EMSG(_(e_float_as_string)); | 5340 #endif |
5331 return FAIL; | 5341 case VAR_SPECIAL: |
5332 } | 5342 if (verbose) |
5333 #endif | 5343 EMSG(_("E909: Cannot index a special variable")); |
5334 else if (rettv->v_type == VAR_SPECIAL) | 5344 return FAIL; |
5335 { | 5345 case VAR_UNKNOWN: |
5336 return FAIL; | 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; | |
5337 } | 5355 } |
5338 | 5356 |
5339 init_tv(&var1); | 5357 init_tv(&var1); |
5340 init_tv(&var2); | 5358 init_tv(&var2); |
5341 if (**arg == '.') | 5359 if (**arg == '.') |
5426 } | 5444 } |
5427 } | 5445 } |
5428 | 5446 |
5429 switch (rettv->v_type) | 5447 switch (rettv->v_type) |
5430 { | 5448 { |
5449 case VAR_SPECIAL: | |
5450 case VAR_FUNC: | |
5451 case VAR_FLOAT: | |
5452 case VAR_UNKNOWN: | |
5453 break; /* not evaluating, skipping over subscript */ | |
5454 | |
5431 case VAR_NUMBER: | 5455 case VAR_NUMBER: |
5432 case VAR_STRING: | 5456 case VAR_STRING: |
5433 s = get_tv_string(rettv); | 5457 s = get_tv_string(rettv); |
5434 len = (long)STRLEN(s); | 5458 len = (long)STRLEN(s); |
5435 if (range) | 5459 if (range) |
6141 return TRUE; | 6165 return TRUE; |
6142 } | 6166 } |
6143 | 6167 |
6144 switch (tv1->v_type) | 6168 switch (tv1->v_type) |
6145 { | 6169 { |
6170 case VAR_UNKNOWN: | |
6171 break; | |
6172 | |
6146 case VAR_LIST: | 6173 case VAR_LIST: |
6147 ++recursive_cnt; | 6174 ++recursive_cnt; |
6148 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE); | 6175 r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE); |
6149 --recursive_cnt; | 6176 --recursive_cnt; |
6150 return r; | 6177 return r; |
6175 | 6202 |
6176 case VAR_SPECIAL: | 6203 case VAR_SPECIAL: |
6177 return tv1->vval.v_number == tv2->vval.v_number; | 6204 return tv1->vval.v_number == tv2->vval.v_number; |
6178 } | 6205 } |
6179 | 6206 |
6180 EMSG2(_(e_intern2), "tv_equal()"); | 6207 /* VAR_UNKNOWN can be the result of a invalid expression, let's say it |
6181 return TRUE; | 6208 * does not equal anything, not even itself. */ |
6209 return FALSE; | |
6182 } | 6210 } |
6183 | 6211 |
6184 /* | 6212 /* |
6185 * Locate item with index "n" in list "l" and return it. | 6213 * Locate item with index "n" in list "l" and return it. |
6186 * A negative index is counted from the end; -1 is the last item. | 6214 * A negative index is counted from the end; -1 is the last item. |
7045 { | 7073 { |
7046 dict_T *dd; | 7074 dict_T *dd; |
7047 list_T *ll; | 7075 list_T *ll; |
7048 int abort = FALSE; | 7076 int abort = FALSE; |
7049 | 7077 |
7050 switch (tv->v_type) | 7078 if (tv->v_type == VAR_DICT) |
7051 { | 7079 { |
7052 case VAR_DICT: | 7080 dd = tv->vval.v_dict; |
7053 dd = tv->vval.v_dict; | 7081 if (dd != NULL && dd->dv_copyID != copyID) |
7054 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) | |
7055 { | 7086 { |
7056 /* Didn't see this dict yet. */ | 7087 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); |
7057 dd->dv_copyID = copyID; | 7088 } |
7058 if (ht_stack == NULL) | 7089 else |
7059 { | 7090 { |
7060 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); | 7091 ht_stack_T *newitem = (ht_stack_T*)malloc(sizeof(ht_stack_T)); |
7061 } | 7092 if (newitem == NULL) |
7093 abort = TRUE; | |
7062 else | 7094 else |
7063 { | 7095 { |
7064 ht_stack_T *newitem = (ht_stack_T*)malloc( | 7096 newitem->ht = &dd->dv_hashtab; |
7065 sizeof(ht_stack_T)); | 7097 newitem->prev = *ht_stack; |
7066 if (newitem == NULL) | 7098 *ht_stack = newitem; |
7067 abort = TRUE; | |
7068 else | |
7069 { | |
7070 newitem->ht = &dd->dv_hashtab; | |
7071 newitem->prev = *ht_stack; | |
7072 *ht_stack = newitem; | |
7073 } | |
7074 } | 7099 } |
7075 } | 7100 } |
7076 break; | 7101 } |
7077 | 7102 } |
7078 case VAR_LIST: | 7103 else if (tv->v_type == VAR_LIST) |
7079 ll = tv->vval.v_list; | 7104 { |
7080 if (ll != NULL && ll->lv_copyID != copyID) | 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) | |
7081 { | 7111 { |
7082 /* Didn't see this list yet. */ | 7112 abort = set_ref_in_list(ll, copyID, ht_stack); |
7083 ll->lv_copyID = copyID; | 7113 } |
7084 if (list_stack == NULL) | 7114 else |
7085 { | 7115 { |
7086 abort = set_ref_in_list(ll, copyID, ht_stack); | 7116 list_stack_T *newitem = (list_stack_T*)malloc( |
7087 } | 7117 sizeof(list_stack_T)); |
7118 if (newitem == NULL) | |
7119 abort = TRUE; | |
7088 else | 7120 else |
7089 { | 7121 { |
7090 list_stack_T *newitem = (list_stack_T*)malloc( | 7122 newitem->list = ll; |
7091 sizeof(list_stack_T)); | 7123 newitem->prev = *list_stack; |
7092 if (newitem == NULL) | 7124 *list_stack = newitem; |
7093 abort = TRUE; | |
7094 else | |
7095 { | |
7096 newitem->list = ll; | |
7097 newitem->prev = *list_stack; | |
7098 *list_stack = newitem; | |
7099 } | |
7100 } | 7125 } |
7101 } | 7126 } |
7102 break; | 7127 } |
7103 } | 7128 } |
7104 return abort; | 7129 return abort; |
7105 } | 7130 } |
7106 | 7131 |
7107 /* | 7132 /* |
7761 } | 7786 } |
7762 break; | 7787 break; |
7763 | 7788 |
7764 case VAR_STRING: | 7789 case VAR_STRING: |
7765 case VAR_NUMBER: | 7790 case VAR_NUMBER: |
7791 case VAR_UNKNOWN: | |
7766 *tofree = NULL; | 7792 *tofree = NULL; |
7767 r = get_tv_string_buf(tv, numbuf); | 7793 r = get_tv_string_buf(tv, numbuf); |
7768 break; | 7794 break; |
7769 | 7795 |
7770 #ifdef FEAT_FLOAT | 7796 #ifdef FEAT_FLOAT |
7777 | 7803 |
7778 case VAR_SPECIAL: | 7804 case VAR_SPECIAL: |
7779 *tofree = NULL; | 7805 *tofree = NULL; |
7780 r = (char_u *)get_var_special_name(tv->vval.v_number); | 7806 r = (char_u *)get_var_special_name(tv->vval.v_number); |
7781 break; | 7807 break; |
7782 | |
7783 default: | |
7784 EMSG2(_(e_intern2), "echo_string()"); | |
7785 *tofree = NULL; | |
7786 } | 7808 } |
7787 | 7809 |
7788 if (--recurse == 0) | 7810 if (--recurse == 0) |
7789 did_echo_string_emsg = FALSE; | 7811 did_echo_string_emsg = FALSE; |
7790 return r; | 7812 return r; |
7820 #endif | 7842 #endif |
7821 case VAR_NUMBER: | 7843 case VAR_NUMBER: |
7822 case VAR_LIST: | 7844 case VAR_LIST: |
7823 case VAR_DICT: | 7845 case VAR_DICT: |
7824 case VAR_SPECIAL: | 7846 case VAR_SPECIAL: |
7847 case VAR_UNKNOWN: | |
7825 break; | 7848 break; |
7826 default: | |
7827 EMSG2(_(e_intern2), "tv2string()"); | |
7828 } | 7849 } |
7829 return echo_string(tv, tofree, numbuf, copyID); | 7850 return echo_string(tv, tofree, numbuf, copyID); |
7830 } | 7851 } |
7831 | 7852 |
7832 /* | 7853 /* |
10526 break; | 10547 break; |
10527 case VAR_SPECIAL: | 10548 case VAR_SPECIAL: |
10528 n = argvars[0].vval.v_number != VVAL_TRUE; | 10549 n = argvars[0].vval.v_number != VVAL_TRUE; |
10529 break; | 10550 break; |
10530 | 10551 |
10531 default: | 10552 case VAR_UNKNOWN: |
10532 EMSG2(_(e_intern2), "f_empty()"); | 10553 EMSG2(_(e_intern2), "f_empty(UNKNOWN)"); |
10533 n = 0; | 10554 n = TRUE; |
10555 break; | |
10534 } | 10556 } |
10535 | 10557 |
10536 rettv->vval.v_number = n; | 10558 rettv->vval.v_number = n; |
10537 } | 10559 } |
10538 | 10560 |
14264 rettv->vval.v_number = list_len(argvars[0].vval.v_list); | 14286 rettv->vval.v_number = list_len(argvars[0].vval.v_list); |
14265 break; | 14287 break; |
14266 case VAR_DICT: | 14288 case VAR_DICT: |
14267 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); | 14289 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); |
14268 break; | 14290 break; |
14269 default: | 14291 case VAR_UNKNOWN: |
14292 case VAR_SPECIAL: | |
14293 case VAR_FLOAT: | |
14294 case VAR_FUNC: | |
14270 EMSG(_("E701: Invalid type for len()")); | 14295 EMSG(_("E701: Invalid type for len()")); |
14271 break; | 14296 break; |
14272 } | 14297 } |
14273 } | 14298 } |
14274 | 14299 |
19622 case VAR_DICT: n = 4; break; | 19647 case VAR_DICT: n = 4; break; |
19623 #ifdef FEAT_FLOAT | 19648 #ifdef FEAT_FLOAT |
19624 case VAR_FLOAT: n = 5; break; | 19649 case VAR_FLOAT: n = 5; break; |
19625 #endif | 19650 #endif |
19626 case VAR_SPECIAL: | 19651 case VAR_SPECIAL: |
19627 if (argvars[0].vval.v_number == VVAL_FALSE | 19652 if (argvars[0].vval.v_number == VVAL_FALSE |
19628 || argvars[0].vval.v_number == VVAL_TRUE) | 19653 || argvars[0].vval.v_number == VVAL_TRUE) |
19629 n = 6; | 19654 n = 6; |
19630 else | 19655 else |
19631 n = 7; | 19656 n = 7; |
19632 break; | 19657 break; |
19633 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; | 19658 case VAR_UNKNOWN: |
19659 EMSG2(_(e_intern2), "f_type(UNKNOWN)"); | |
19660 n = -1; | |
19661 break; | |
19634 } | 19662 } |
19635 rettv->vval.v_number = n; | 19663 rettv->vval.v_number = n; |
19636 } | 19664 } |
19637 | 19665 |
19638 /* | 19666 /* |
20997 #ifdef FEAT_FLOAT | 21025 #ifdef FEAT_FLOAT |
20998 case VAR_FLOAT: | 21026 case VAR_FLOAT: |
20999 #endif | 21027 #endif |
21000 case VAR_UNKNOWN: | 21028 case VAR_UNKNOWN: |
21001 case VAR_SPECIAL: | 21029 case VAR_SPECIAL: |
21002 break; | |
21003 default: | |
21004 EMSG2(_(e_intern2), "free_tv()"); | |
21005 break; | 21030 break; |
21006 } | 21031 } |
21007 vim_free(varp); | 21032 vim_free(varp); |
21008 } | 21033 } |
21009 } | 21034 } |
21042 varp->vval.v_float = 0.0; | 21067 varp->vval.v_float = 0.0; |
21043 break; | 21068 break; |
21044 #endif | 21069 #endif |
21045 case VAR_UNKNOWN: | 21070 case VAR_UNKNOWN: |
21046 break; | 21071 break; |
21047 default: | |
21048 EMSG2(_(e_intern2), "clear_tv()"); | |
21049 } | 21072 } |
21050 varp->v_lock = 0; | 21073 varp->v_lock = 0; |
21051 } | 21074 } |
21052 } | 21075 } |
21053 | 21076 |
21106 EMSG(_("E728: Using a Dictionary as a Number")); | 21129 EMSG(_("E728: Using a Dictionary as a Number")); |
21107 break; | 21130 break; |
21108 case VAR_SPECIAL: | 21131 case VAR_SPECIAL: |
21109 return varp->vval.v_number == VVAL_TRUE ? 1 : 0; | 21132 return varp->vval.v_number == VVAL_TRUE ? 1 : 0; |
21110 break; | 21133 break; |
21111 default: | 21134 case VAR_UNKNOWN: |
21112 EMSG2(_(e_intern2), "get_tv_number()"); | 21135 EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)"); |
21113 break; | 21136 break; |
21114 } | 21137 } |
21115 if (denote == NULL) /* useful for values that must be unsigned */ | 21138 if (denote == NULL) /* useful for values that must be unsigned */ |
21116 n = -1; | 21139 n = -1; |
21117 else | 21140 else |
21128 case VAR_NUMBER: | 21151 case VAR_NUMBER: |
21129 return (float_T)(varp->vval.v_number); | 21152 return (float_T)(varp->vval.v_number); |
21130 #ifdef FEAT_FLOAT | 21153 #ifdef FEAT_FLOAT |
21131 case VAR_FLOAT: | 21154 case VAR_FLOAT: |
21132 return varp->vval.v_float; | 21155 return varp->vval.v_float; |
21133 break; | |
21134 #endif | 21156 #endif |
21135 case VAR_FUNC: | 21157 case VAR_FUNC: |
21136 EMSG(_("E891: Using a Funcref as a Float")); | 21158 EMSG(_("E891: Using a Funcref as a Float")); |
21137 break; | 21159 break; |
21138 case VAR_STRING: | 21160 case VAR_STRING: |
21142 EMSG(_("E893: Using a List as a Float")); | 21164 EMSG(_("E893: Using a List as a Float")); |
21143 break; | 21165 break; |
21144 case VAR_DICT: | 21166 case VAR_DICT: |
21145 EMSG(_("E894: Using a Dictionary as a Float")); | 21167 EMSG(_("E894: Using a Dictionary as a Float")); |
21146 break; | 21168 break; |
21147 default: | 21169 case VAR_SPECIAL: |
21148 EMSG2(_(e_intern2), "get_tv_float()"); | 21170 EMSG(_("E907: Using a special value as a Float")); |
21171 break; | |
21172 case VAR_UNKNOWN: | |
21173 EMSG2(_(e_intern2), "get_tv_float(UNKNOWN)"); | |
21149 break; | 21174 break; |
21150 } | 21175 } |
21151 return 0; | 21176 return 0; |
21152 } | 21177 } |
21153 #endif | 21178 #endif |
21254 return varp->vval.v_string; | 21279 return varp->vval.v_string; |
21255 return (char_u *)""; | 21280 return (char_u *)""; |
21256 case VAR_SPECIAL: | 21281 case VAR_SPECIAL: |
21257 STRCPY(buf, get_var_special_name(varp->vval.v_number)); | 21282 STRCPY(buf, get_var_special_name(varp->vval.v_number)); |
21258 return buf; | 21283 return buf; |
21259 | 21284 case VAR_UNKNOWN: |
21260 default: | 21285 EMSG(_("E908: using an invalid value as a String")); |
21261 EMSG2(_(e_intern2), "get_tv_string_buf()"); | |
21262 break; | 21286 break; |
21263 } | 21287 } |
21264 return NULL; | 21288 return NULL; |
21265 } | 21289 } |
21266 | 21290 |
21908 { | 21932 { |
21909 to->vval.v_dict = from->vval.v_dict; | 21933 to->vval.v_dict = from->vval.v_dict; |
21910 ++to->vval.v_dict->dv_refcount; | 21934 ++to->vval.v_dict->dv_refcount; |
21911 } | 21935 } |
21912 break; | 21936 break; |
21913 default: | 21937 case VAR_UNKNOWN: |
21914 EMSG2(_(e_intern2), "copy_tv()"); | 21938 EMSG2(_(e_intern2), "copy_tv(UNKNOWN)"); |
21915 break; | 21939 break; |
21916 } | 21940 } |
21917 } | 21941 } |
21918 | 21942 |
21919 /* | 21943 /* |
21981 else | 22005 else |
21982 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); | 22006 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); |
21983 if (to->vval.v_dict == NULL) | 22007 if (to->vval.v_dict == NULL) |
21984 ret = FAIL; | 22008 ret = FAIL; |
21985 break; | 22009 break; |
21986 default: | 22010 case VAR_UNKNOWN: |
21987 EMSG2(_(e_intern2), "item_copy()"); | 22011 EMSG2(_(e_intern2), "item_copy(UNKNOWN)"); |
21988 ret = FAIL; | 22012 ret = FAIL; |
21989 } | 22013 } |
21990 --recurse; | 22014 --recurse; |
21991 return ret; | 22015 return ret; |
21992 } | 22016 } |
24530 #ifdef FEAT_FLOAT | 24554 #ifdef FEAT_FLOAT |
24531 case 'F': type = VAR_FLOAT; break; | 24555 case 'F': type = VAR_FLOAT; break; |
24532 #endif | 24556 #endif |
24533 case 'D': type = VAR_DICT; break; | 24557 case 'D': type = VAR_DICT; break; |
24534 case 'L': type = VAR_LIST; break; | 24558 case 'L': type = VAR_LIST; break; |
24559 case 'X': type = VAR_SPECIAL; break; | |
24535 } | 24560 } |
24536 | 24561 |
24537 tab = vim_strchr(tab, '\t'); | 24562 tab = vim_strchr(tab, '\t'); |
24538 if (tab != NULL) | 24563 if (tab != NULL) |
24539 { | 24564 { |
24615 #ifdef FEAT_FLOAT | 24640 #ifdef FEAT_FLOAT |
24616 case VAR_FLOAT: s = "FLO"; break; | 24641 case VAR_FLOAT: s = "FLO"; break; |
24617 #endif | 24642 #endif |
24618 case VAR_DICT: s = "DIC"; break; | 24643 case VAR_DICT: s = "DIC"; break; |
24619 case VAR_LIST: s = "LIS"; break; | 24644 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; | |
24621 } | 24650 } |
24622 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); | 24651 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); |
24623 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); | 24652 p = echo_string(&this_var->di_tv, &tofree, numbuf, 0); |
24624 if (p != NULL) | 24653 if (p != NULL) |
24625 viminfo_writestring(fp, p); | 24654 viminfo_writestring(fp, p); |