]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 7.4.1267 v7.4.1267
authorBram Moolenaar <Bram@vim.org>
Sat, 6 Feb 2016 17:09:59 +0000 (18:09 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 6 Feb 2016 17:09:59 +0000 (18:09 +0100)
Problem:    Easy to miss handling all types of variables.
Solution:   Change the variable type into an enum.

src/eval.c
src/structs.h
src/version.c

index 33ec495e83dd0b6d0aab6f3a71e910778bde91bd..7ce739ce785c43fa0b31d2cca4182bed379b8ee6 100644 (file)
@@ -3065,6 +3065,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
            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 lock)
 
     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)
+    switch (rettv->v_type)
     {
-       if (verbose)
-           EMSG(_("E695: Cannot index a Funcref"));
-       return FAIL;
-    }
+       case VAR_FUNC:
+           if (verbose)
+               EMSG(_("E695: Cannot index a Funcref"));
+           return FAIL;
+       case VAR_FLOAT:
 #ifdef FEAT_FLOAT
-    else if (rettv->v_type == VAR_FLOAT)
-    {
-       if (verbose)
-           EMSG(_(e_float_as_string));
-       return FAIL;
-    }
+           if (verbose)
+               EMSG(_(e_float_as_string));
+           return FAIL;
 #endif
-    else if (rettv->v_type == VAR_SPECIAL)
-    {
-       return FAIL;
+       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)
+    if (tv->v_type == VAR_DICT)
     {
-       case VAR_DICT:
-           dd = tv->vval.v_dict;
-           if (dd != NULL && dd->dv_copyID != copyID)
+       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)
            {
-               /* 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);
-               }
+               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
                {
-                   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;
-                   }
+                   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)
+       }
+    }
+    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)
            {
-               /* Didn't see this list yet. */
-               ll->lv_copyID = copyID;
-               if (list_stack == NULL)
-               {
-                   abort = set_ref_in_list(ll, copyID, ht_stack);
-               }
+               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
                {
-                   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;
-                   }
+                   newitem->list = ll;
+                   newitem->prev = *list_stack;
+                   *list_stack = newitem;
                }
            }
-           break;
+       }
     }
     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:
+       case VAR_UNKNOWN:
            break;
-       default:
-           EMSG2(_(e_intern2), "tv2string()");
     }
     return echo_string(tv, tofree, numbuf, copyID);
 }
@@ -10528,9 +10549,10 @@ f_empty(typval_T *argvars, typval_T *rettv)
            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 *rettv)
        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 *denote)
        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, char_u *buf)
        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 writing)
 #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);
index 26f403f2a8581166f34aa30ffb4b4257f8f89033..d10547acf0aa7e6d762d3dd0ba9ac92fbb70dfc4 100644 (file)
@@ -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
index 51f0503c699ada6b40f8e9684575c4d877ca3e12..47f45deef9153322c41caae728943b2db710681d 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1267,
 /**/
     1266,
 /**/