# HG changeset patch # User Bram Moolenaar # Date 1578755704 -3600 # Node ID ba9f50bfda8364653f7a53766fc21c5930f62026 # Parent 7c682fab000b0f7fa2e54080ceae1931161da43b patch 8.2.0111: VAR_SPECIAL is also used for booleans Commit: https://github.com/vim/vim/commit/9b4a15d5dba354d2e1e02871470bad103f34769a Author: Bram Moolenaar Date: Sat Jan 11 16:05:23 2020 +0100 patch 8.2.0111: VAR_SPECIAL is also used for booleans Problem: VAR_SPECIAL is also used for booleans. Solution: Add VAR_BOOL for better type checking. diff --git a/src/dict.c b/src/dict.c --- a/src/dict.c +++ b/src/dict.c @@ -345,14 +345,14 @@ dict_add(dict_T *d, dictitem_T *item) * Returns FAIL when out of memory and when key already exists. */ static int -dict_add_number_special(dict_T *d, char *key, varnumber_T nr, int special) +dict_add_number_special(dict_T *d, char *key, varnumber_T nr, vartype_T vartype) { dictitem_T *item; item = dictitem_alloc((char_u *)key); if (item == NULL) return FAIL; - item->di_tv.v_type = special ? VAR_SPECIAL : VAR_NUMBER; + item->di_tv.v_type = vartype; item->di_tv.vval.v_number = nr; if (dict_add(d, item) == FAIL) { @@ -369,7 +369,7 @@ dict_add_number_special(dict_T *d, char int dict_add_number(dict_T *d, char *key, varnumber_T nr) { - return dict_add_number_special(d, key, nr, FALSE); + return dict_add_number_special(d, key, nr, VAR_NUMBER); } /* @@ -377,9 +377,9 @@ dict_add_number(dict_T *d, char *key, va * Returns FAIL when out of memory and when key already exists. */ int -dict_add_special(dict_T *d, char *key, varnumber_T nr) +dict_add_bool(dict_T *d, char *key, varnumber_T nr) { - return dict_add_number_special(d, key, nr, TRUE); + return dict_add_number_special(d, key, nr, VAR_BOOL); } /* diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -1246,7 +1246,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char // Can't do anything with a Funcref, Dict, v:true on the right. if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT - && tv2->v_type != VAR_SPECIAL) + && tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL) { switch (tv1->v_type) { @@ -1254,6 +1254,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char case VAR_DICT: case VAR_FUNC: case VAR_PARTIAL: + case VAR_BOOL: case VAR_SPECIAL: case VAR_JOB: case VAR_CHANNEL: @@ -3016,6 +3017,7 @@ eval_index( emsg(_(e_float_as_string)); return FAIL; #endif + case VAR_BOOL: case VAR_SPECIAL: case VAR_JOB: case VAR_CHANNEL: @@ -3131,6 +3133,7 @@ eval_index( case VAR_FUNC: case VAR_PARTIAL: case VAR_FLOAT: + case VAR_BOOL: case VAR_SPECIAL: case VAR_JOB: case VAR_CHANNEL: @@ -3777,6 +3780,7 @@ tv_equal( s2 = tv_get_string_buf(tv2, buf2); return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); + case VAR_BOOL: case VAR_SPECIAL: return tv1->vval.v_number == tv2->vval.v_number; @@ -4531,6 +4535,7 @@ echo_string_core( break; #endif + case VAR_BOOL: case VAR_SPECIAL: *tofree = NULL; r = (char_u *)get_var_special_name(tv->vval.v_number); @@ -5359,6 +5364,7 @@ free_tv(typval_T *varp) case VAR_NUMBER: case VAR_FLOAT: case VAR_UNKNOWN: + case VAR_BOOL: case VAR_SPECIAL: break; } @@ -5399,6 +5405,7 @@ clear_tv(typval_T *varp) varp->vval.v_dict = NULL; break; case VAR_NUMBER: + case VAR_BOOL: case VAR_SPECIAL: varp->vval.v_number = 0; break; @@ -5480,6 +5487,7 @@ tv_get_number_chk(typval_T *varp, int *d case VAR_DICT: emsg(_("E728: Using a Dictionary as a Number")); break; + case VAR_BOOL: case VAR_SPECIAL: return varp->vval.v_number == VVAL_TRUE ? 1 : 0; case VAR_JOB: @@ -5529,6 +5537,9 @@ tv_get_float(typval_T *varp) case VAR_DICT: emsg(_("E894: Using a Dictionary as a Float")); break; + case VAR_BOOL: + emsg(_("E362: Using a boolean value as a Float")); + break; case VAR_SPECIAL: emsg(_("E907: Using a special value as a Float")); break; @@ -5618,6 +5629,7 @@ tv_get_string_buf_chk(typval_T *varp, ch if (varp->vval.v_string != NULL) return varp->vval.v_string; return (char_u *)""; + case VAR_BOOL: case VAR_SPECIAL: STRCPY(buf, get_var_special_name(varp->vval.v_number)); return buf; @@ -5744,6 +5756,7 @@ copy_tv(typval_T *from, typval_T *to) switch (from->v_type) { case VAR_NUMBER: + case VAR_BOOL: case VAR_SPECIAL: to->vval.v_number = from->vval.v_number; break; @@ -5850,6 +5863,7 @@ item_copy( case VAR_STRING: case VAR_FUNC: case VAR_PARTIAL: + case VAR_BOOL: case VAR_SPECIAL: case VAR_JOB: case VAR_CHANNEL: diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -1067,7 +1067,7 @@ non_zero_arg(typval_T *argvars) { return ((argvars[0].v_type == VAR_NUMBER && argvars[0].vval.v_number != 0) - || (argvars[0].v_type == VAR_SPECIAL + || (argvars[0].v_type == VAR_BOOL && argvars[0].vval.v_number == VVAL_TRUE) || (argvars[0].v_type == VAR_STRING && argvars[0].vval.v_string != NULL @@ -1811,6 +1811,7 @@ f_empty(typval_T *argvars, typval_T *ret n = argvars[0].vval.v_dict == NULL || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; break; + case VAR_BOOL: case VAR_SPECIAL: n = argvars[0].vval.v_number != VVAL_TRUE; break; @@ -4318,6 +4319,7 @@ f_len(typval_T *argvars, typval_T *rettv rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); break; case VAR_UNKNOWN: + case VAR_BOOL: case VAR_SPECIAL: case VAR_FLOAT: case VAR_FUNC: @@ -8341,20 +8343,15 @@ f_type(typval_T *argvars, typval_T *rett switch (argvars[0].v_type) { - case VAR_NUMBER: n = VAR_TYPE_NUMBER; break; - case VAR_STRING: n = VAR_TYPE_STRING; break; + case VAR_NUMBER: n = VAR_TYPE_NUMBER; break; + case VAR_STRING: n = VAR_TYPE_STRING; break; case VAR_PARTIAL: - case VAR_FUNC: n = VAR_TYPE_FUNC; break; - case VAR_LIST: n = VAR_TYPE_LIST; break; - case VAR_DICT: n = VAR_TYPE_DICT; break; - case VAR_FLOAT: n = VAR_TYPE_FLOAT; break; - case VAR_SPECIAL: - if (argvars[0].vval.v_number == VVAL_FALSE - || argvars[0].vval.v_number == VVAL_TRUE) - n = VAR_TYPE_BOOL; - else - n = VAR_TYPE_NONE; - break; + case VAR_FUNC: n = VAR_TYPE_FUNC; break; + case VAR_LIST: n = VAR_TYPE_LIST; break; + case VAR_DICT: n = VAR_TYPE_DICT; break; + case VAR_FLOAT: n = VAR_TYPE_FLOAT; break; + case VAR_BOOL: n = VAR_TYPE_BOOL; break; + case VAR_SPECIAL: n = VAR_TYPE_NONE; break; case VAR_JOB: n = VAR_TYPE_JOB; break; case VAR_CHANNEL: n = VAR_TYPE_CHANNEL; break; case VAR_BLOB: n = VAR_TYPE_BLOB; break; diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -118,8 +118,8 @@ static struct vimvar {VV_NAME("option_command", VAR_STRING), VV_RO}, {VV_NAME("option_type", VAR_STRING), VV_RO}, {VV_NAME("errors", VAR_LIST), 0}, - {VV_NAME("false", VAR_SPECIAL), VV_RO}, - {VV_NAME("true", VAR_SPECIAL), VV_RO}, + {VV_NAME("false", VAR_BOOL), VV_RO}, + {VV_NAME("true", VAR_BOOL), VV_RO}, {VV_NAME("null", VAR_SPECIAL), VV_RO}, {VV_NAME("none", VAR_SPECIAL), VV_RO}, {VV_NAME("vim_did_enter", VAR_NUMBER), VV_RO}, @@ -1675,6 +1675,7 @@ item_lock(typval_T *tv, int deep, int lo case VAR_FUNC: case VAR_PARTIAL: case VAR_FLOAT: + case VAR_BOOL: case VAR_SPECIAL: case VAR_JOB: case VAR_CHANNEL: diff --git a/src/if_lua.c b/src/if_lua.c --- a/src/if_lua.c +++ b/src/if_lua.c @@ -535,6 +535,7 @@ luaV_pushtypval(lua_State *L, typval_T * case VAR_DICT: luaV_pushdict(L, tv->vval.v_dict); break; + case VAR_BOOL: case VAR_SPECIAL: if (tv->vval.v_number <= VVAL_TRUE) lua_pushinteger(L, (int) tv->vval.v_number); @@ -564,7 +565,7 @@ luaV_totypval(lua_State *L, int pos, typ switch (lua_type(L, pos)) { case LUA_TBOOLEAN: - tv->v_type = VAR_SPECIAL; + tv->v_type = VAR_BOOL; tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos); break; case LUA_TNIL: diff --git a/src/if_mzsch.c b/src/if_mzsch.c --- a/src/if_mzsch.c +++ b/src/if_mzsch.c @@ -3136,7 +3136,7 @@ vim_to_mzscheme_impl(typval_T *vim_value MZ_GC_UNREG(); } } - else if (vim_value->v_type == VAR_SPECIAL) + else if (vim_value->v_type == VAR_BOOL || vim_value->v_type == VAR_SPECIAL) { if (vim_value->vval.v_number <= VVAL_TRUE) result = scheme_make_integer((long)vim_value->vval.v_number); @@ -3218,7 +3218,7 @@ mzscheme_to_vim_impl(Scheme_Object *obj, } else if (SCHEME_BOOLP(obj)) { - tv->v_type = VAR_SPECIAL; + tv->v_type = VAR_BOOL; tv->vval.v_number = SCHEME_TRUEP(obj); } # ifdef FEAT_FLOAT diff --git a/src/if_py_both.h b/src/if_py_both.h --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -844,23 +844,24 @@ VimToPython(typval_T *our_tv, int depth, } } } - else if (our_tv->v_type == VAR_SPECIAL) + else if (our_tv->v_type == VAR_BOOL) { if (our_tv->vval.v_number == VVAL_FALSE) { ret = Py_False; Py_INCREF(ret); } - else if (our_tv->vval.v_number == VVAL_TRUE) + else { ret = Py_True; Py_INCREF(ret); } - else - { - Py_INCREF(Py_None); - ret = Py_None; - } + return ret; + } + else if (our_tv->v_type == VAR_SPECIAL) + { + Py_INCREF(Py_None); + ret = Py_None; return ret; } else if (our_tv->v_type == VAR_BLOB) @@ -6389,6 +6390,7 @@ ConvertToPyObject(typval_T *tv) case VAR_JOB: Py_INCREF(Py_None); return Py_None; + case VAR_BOOL: case VAR_SPECIAL: switch (tv->vval.v_number) { diff --git a/src/if_ruby.c b/src/if_ruby.c --- a/src/if_ruby.c +++ b/src/if_ruby.c @@ -1183,7 +1183,7 @@ vim_to_ruby(typval_T *tv) } } } - else if (tv->v_type == VAR_SPECIAL) + else if (tv->v_type == VAR_BOOL || tv->v_type == VAR_SPECIAL) { if (tv->vval.v_number == VVAL_TRUE) result = Qtrue; @@ -1827,11 +1827,11 @@ ruby_convert_to_vim_value(VALUE val, typ rettv->vval.v_number = VVAL_NULL; break; case T_TRUE: - rettv->v_type = VAR_SPECIAL; + rettv->v_type = VAR_BOOL; rettv->vval.v_number = VVAL_TRUE; break; case T_FALSE: - rettv->v_type = VAR_SPECIAL; + rettv->v_type = VAR_BOOL; rettv->vval.v_number = VVAL_FALSE; break; case T_BIGNUM: diff --git a/src/json.c b/src/json.c --- a/src/json.c +++ b/src/json.c @@ -193,11 +193,17 @@ json_encode_item(garray_T *gap, typval_T switch (val->v_type) { - case VAR_SPECIAL: + case VAR_BOOL: switch (val->vval.v_number) { case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break; case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break; + } + break; + + case VAR_SPECIAL: + switch (val->vval.v_number) + { case VVAL_NONE: if ((options & JSON_JS) != 0 && (options & JSON_NO_NONE) == 0) // empty item @@ -818,7 +824,7 @@ json_decode_item(js_read_T *reader, typv reader->js_used += 5; if (cur_item != NULL) { - cur_item->v_type = VAR_SPECIAL; + cur_item->v_type = VAR_BOOL; cur_item->vval.v_number = VVAL_FALSE; } retval = OK; @@ -829,7 +835,7 @@ json_decode_item(js_read_T *reader, typv reader->js_used += 4; if (cur_item != NULL) { - cur_item->v_type = VAR_SPECIAL; + cur_item->v_type = VAR_BOOL; cur_item->vval.v_number = VVAL_TRUE; } retval = OK; diff --git a/src/popupmenu.c b/src/popupmenu.c --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -1076,7 +1076,7 @@ pum_set_event_info(dict_T *dict) dict_add_number(dict, "row", pum_row); dict_add_number(dict, "col", pum_col); dict_add_number(dict, "size", pum_size); - dict_add_special(dict, "scrollbar", pum_scrollbar ? VVAL_TRUE : VVAL_FALSE); + dict_add_bool(dict, "scrollbar", pum_scrollbar ? VVAL_TRUE : VVAL_FALSE); } #endif diff --git a/src/proto/dict.pro b/src/proto/dict.pro --- a/src/proto/dict.pro +++ b/src/proto/dict.pro @@ -14,7 +14,7 @@ void dictitem_free(dictitem_T *item); dict_T *dict_copy(dict_T *orig, int deep, int copyID); int dict_add(dict_T *d, dictitem_T *item); int dict_add_number(dict_T *d, char *key, varnumber_T nr); -int dict_add_special(dict_T *d, char *key, varnumber_T nr); +int dict_add_bool(dict_T *d, char *key, varnumber_T nr); int dict_add_string(dict_T *d, char *key, char_u *str); int dict_add_string_len(dict_T *d, char *key, char_u *str, int len); int dict_add_list(dict_T *d, char *key, list_T *list); diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1313,7 +1313,8 @@ typedef enum VAR_LIST, // "v_list" is used VAR_DICT, // "v_dict" is used VAR_FLOAT, // "v_float" is used - VAR_SPECIAL, // "v_number" is used + VAR_BOOL, // "v_number" is VVAL_FALSE or VVAL_TRUE + VAR_SPECIAL, // "v_number" is VVAL_NONE or VVAL_NULL VAR_JOB, // "v_job" is used VAR_CHANNEL, // "v_channel" is used VAR_BLOB, // "v_blob" is used diff --git a/src/testing.c b/src/testing.c --- a/src/testing.c +++ b/src/testing.c @@ -222,7 +222,7 @@ assert_bool(typval_T *argvars, int isTru int error = FALSE; garray_T ga; - if (argvars[0].v_type == VAR_SPECIAL + if (argvars[0].v_type == VAR_BOOL && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE)) return 0; if (argvars[0].v_type != VAR_NUMBER @@ -760,6 +760,7 @@ f_test_refcount(typval_T *argvars, typva case VAR_UNKNOWN: case VAR_NUMBER: case VAR_FLOAT: + case VAR_BOOL: case VAR_SPECIAL: case VAR_STRING: break; 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 */ /**/ + 111, +/**/ 110, /**/ 109, diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -2019,11 +2019,11 @@ typedef int sock_T; #define VV_ARGV 93 #define VV_LEN 94 // number of v: vars -// used for v_number in VAR_SPECIAL -#define VVAL_FALSE 0L -#define VVAL_TRUE 1L -#define VVAL_NONE 2L -#define VVAL_NULL 3L +// used for v_number in VAR_BOOL and VAR_SPECIAL +#define VVAL_FALSE 0L // VAR_BOOL +#define VVAL_TRUE 1L // VAR_BOOL +#define VVAL_NONE 2L // VAR_SPECIAL +#define VVAL_NULL 3L // VAR_SPECIAL // Type values for type(). #define VAR_TYPE_NUMBER 0 diff --git a/src/viminfo.c b/src/viminfo.c --- a/src/viminfo.c +++ b/src/viminfo.c @@ -1233,7 +1233,12 @@ read_viminfo_varlist(vir_T *virp, int wr (void)string2float(tab + 1, &tv.vval.v_float); #endif else + { tv.vval.v_number = atol((char *)tab + 1); + if (type == VAR_SPECIAL && (tv.vval.v_number == VVAL_FALSE + || tv.vval.v_number == VVAL_TRUE)) + tv.v_type = VAR_BOOL; + } if (type == VAR_DICT || type == VAR_LIST) { typval_T *etv = eval_expr(tv.vval.v_string, NULL); @@ -1312,12 +1317,13 @@ write_viminfo_varlist(FILE *fp) { switch (this_var->di_tv.v_type) { - case VAR_STRING: s = "STR"; break; - case VAR_NUMBER: s = "NUM"; break; - case VAR_FLOAT: s = "FLO"; break; - case VAR_DICT: s = "DIC"; break; - case VAR_LIST: s = "LIS"; break; - case VAR_BLOB: s = "BLO"; break; + case VAR_STRING: s = "STR"; break; + case VAR_NUMBER: s = "NUM"; break; + case VAR_FLOAT: s = "FLO"; break; + case VAR_DICT: s = "DIC"; break; + case VAR_LIST: s = "LIS"; break; + case VAR_BLOB: s = "BLO"; break; + case VAR_BOOL: s = "XPL"; break; // backwards compat. case VAR_SPECIAL: s = "XPL"; break; case VAR_UNKNOWN: @@ -1328,8 +1334,10 @@ write_viminfo_varlist(FILE *fp) continue; } fprintf(fp, "!%s\t%s\t", this_var->di_key, s); - if (this_var->di_tv.v_type == VAR_SPECIAL) + if (this_var->di_tv.v_type == VAR_BOOL + || this_var->di_tv.v_type == VAR_SPECIAL) { + // do not use "v:true" but "1" sprintf((char *)numbuf, "%ld", (long)this_var->di_tv.vval.v_number); p = numbuf;