]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0111: VAR_SPECIAL is also used for booleans v8.2.0111
authorBram Moolenaar <Bram@vim.org>
Sat, 11 Jan 2020 15:05:23 +0000 (16:05 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 11 Jan 2020 15:05:23 +0000 (16:05 +0100)
Problem:    VAR_SPECIAL is also used for booleans.
Solution:   Add VAR_BOOL for better type checking.

16 files changed:
src/dict.c
src/eval.c
src/evalfunc.c
src/evalvars.c
src/if_lua.c
src/if_mzsch.c
src/if_py_both.h
src/if_ruby.c
src/json.c
src/popupmenu.c
src/proto/dict.pro
src/structs.h
src/testing.c
src/version.c
src/vim.h
src/viminfo.c

index a9a909bc2a771ba99ca4b979ae59e8139e4141da..f3f3521672fda987dac7fd175c4d8be3a5a3db88 100644 (file)
@@ -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 *key, varnumber_T nr, int special)
     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, varnumber_T nr)
  * 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);
 }
 
 /*
index f8ba4dffa0dd169ba0fc763c39d1ff8aa7b766de..48357d441d991d951584b8ef8cc637a871a77c50 100644 (file)
@@ -1246,7 +1246,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
 
     // 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_u *op)
            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 *denote)
        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, char_u *buf)
            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:
index 003d3b9ff25ef4a93ec6d5aba5d453303903f27f..4465fc07c11a14c46bd490dc0a6bf8c52f52e180 100644 (file)
@@ -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 *rettv)
            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 *rettv)
 
     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;
index 6ec5c25dced8643424ddae6338c2bc29d7854bc0..fbe23c4f16fb92198faba8ea5fbbc432ab36fc48 100644 (file)
@@ -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 lock)
        case VAR_FUNC:
        case VAR_PARTIAL:
        case VAR_FLOAT:
+       case VAR_BOOL:
        case VAR_SPECIAL:
        case VAR_JOB:
        case VAR_CHANNEL:
index 9b03c97aa859e3c6dc14be88ab06405af99744ea..b80b6c9e26c5c9d69c1094d3f30d33be4e43189f 100644 (file)
@@ -535,6 +535,7 @@ luaV_pushtypval(lua_State *L, typval_T *tv)
        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, typval_T *tv)
     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:
index bf0157a59e00722dc4bd9c425ce662829defdeb4..e31d0e110ccc4b25383ad195bd58ff2d6f3df815 100644 (file)
@@ -3136,7 +3136,7 @@ vim_to_mzscheme_impl(typval_T *vim_value, int depth, Scheme_Hash_Table *visited)
            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, typval_T *tv, int depth,
     }
     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
index d816386558b658dde320a2349c2e8299553b28f6..af4b98dd06f50d87604f1c799f6479bdc62e6776 100644 (file)
@@ -844,23 +844,24 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
            }
        }
     }
-    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)
            {
index 68d55821fcc271f6df7215fc735dd70bae046f53..7f2a7d265e19d35e6fa5272ba6b8d587d5f0df74 100644 (file)
@@ -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, typval_T *rettv)
            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:
index eedb6062af1913ec4cc7d8b72e859145a2f93fc8..64ef93fabb4731a848d77640a47dc7371882af82 100644 (file)
@@ -193,11 +193,17 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
 
     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, typval_T *res, int options)
                        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, typval_T *res, int options)
                        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;
index cccde47adacc70cca2d9df063d98d421c27588f5..0e4f9fef076837c2e5479bd8fe5ab7f5a3cd2424 100644 (file)
@@ -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
 
index 75519a404771c60574ed3fa1024b1bba15c522b5..d9b35c30919f68058eebe5d3909a1de439b295ff 100644 (file)
@@ -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);
index 5f32e1d60dadcae65b63c9ac83797ec89686a80a..ffd6734e42bf62ac3e9709567f1b5d85ce207156 100644 (file)
@@ -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
index 3e6ba8e03e9c9c460f6d869652ff935a23444b39..ac9beea435805a69b729946947d0573bf455dd79 100644 (file)
@@ -222,7 +222,7 @@ assert_bool(typval_T *argvars, int isTrue)
     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, typval_T *rettv)
        case VAR_UNKNOWN:
        case VAR_NUMBER:
        case VAR_FLOAT:
+       case VAR_BOOL:
        case VAR_SPECIAL:
        case VAR_STRING:
            break;
index d6386adb8857024d0c74e482a768f349ded4dcf2..7941733cfff222bd8b74ca96e01e837bdc251ae3 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    111,
 /**/
     110,
 /**/
index 1fd24ad3fdaa6b05ba4e9be3e958c3808b0d3a99..16949ae291dd811b41bc5c8c51396a80ce63cc6f 100644 (file)
--- 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
index 308a9a60977f505b6f0eb9a06a5c66dceacc290f..24cd4f7133f8670fd526bcad12a2640dd32e4177 100644 (file)
@@ -1233,7 +1233,12 @@ read_viminfo_varlist(vir_T *virp, int writing)
                    (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;