]> granicus.if.org Git - vim/commitdiff
patch 8.1.0741: viminfo with Blob is not tested v8.1.0741
authorBram Moolenaar <Bram@vim.org>
Sun, 13 Jan 2019 16:48:04 +0000 (17:48 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 13 Jan 2019 16:48:04 +0000 (17:48 +0100)
Problem:    Viminfo with Blob is not tested.
Solution:   Extend the viminfo test.  Fix reading a blob.  Fixed storing a
            special variable value.

src/blob.c
src/eval.c
src/proto/blob.pro
src/testdir/test_viminfo.vim
src/version.c

index c260a435721dbaaa43d84d70710f875225609c91..58acfc816ab8dfb90650a04b52106b7edc7f2587 100644 (file)
@@ -167,4 +167,71 @@ write_blob(FILE *fd, blob_T *blob)
     return OK;
 }
 
+/*
+ * Convert a blob to a readable form: "[0x11,0x34]"
+ */
+    char_u *
+blob2string(blob_T *blob, char_u **tofree, char_u *numbuf)
+{
+    int                i;
+    garray_T    ga;
+
+    if (blob == NULL)
+    {
+       *tofree = NULL;
+       return (char_u *)"[]";
+    }
+
+    // Store bytes in the growarray.
+    ga_init2(&ga, 1, 4000);
+    ga_append(&ga, '[');
+    for (i = 0; i < blob_len(blob); i++)
+    {
+       if (i > 0)
+           ga_concat(&ga, (char_u *)",");
+       vim_snprintf((char *)numbuf, NUMBUFLEN, "0x%02X", (int)blob_get(blob, i));
+       ga_concat(&ga, numbuf);
+    }
+    ga_append(&ga, ']');
+    *tofree = ga.ga_data;
+    return *tofree;
+}
+
+/*
+ * Convert a string variable, in the format of blob2string(), to a blob.
+ * Return NULL when conversion failed.
+ */
+    blob_T *
+string2blob(char_u *str)
+{
+    blob_T  *blob = blob_alloc();
+    char_u  *s = str;
+
+    if (*s != '[')
+       goto failed;
+    s = skipwhite(s + 1);
+    while (*s != ']')
+    {
+       if (s[0] != '0' || s[1] != 'x'
+                                || !vim_isxdigit(s[2]) || !vim_isxdigit(s[3]))
+           goto failed;
+       ga_append(&blob->bv_ga, (hex2nr(s[2]) << 4) + hex2nr(s[3]));
+       s += 4;
+       if (*s == ',')
+           s = skipwhite(s + 1);
+       else if (*s != ']')
+           goto failed;
+    }
+    s = skipwhite(s + 1);
+    if (*s != NUL)
+       goto failed;  // text after final ']'
+
+    ++blob->bv_refcount;
+    return blob;
+
+failed:
+    blob_free(blob);
+    return NULL;
+}
+
 #endif /* defined(FEAT_EVAL) */
index e7dcf07499e7cac3e3230382da86a7b649b802d7..835e44ccea366ff36814478119c21d71cb90bf34 100644 (file)
@@ -5882,33 +5882,7 @@ echo_string_core(
            }
 
        case VAR_BLOB:
-           if (tv->vval.v_blob == NULL)
-           {
-               *tofree = NULL;
-               r = (char_u *)"[]";
-           }
-           else
-           {
-               blob_T      *b;
-               int         i;
-               garray_T    ga;
-
-               // Store bytes in the growarray.
-               ga_init2(&ga, 1, 4000);
-               b = tv->vval.v_blob;
-               ga_append(&ga, '[');
-               for (i = 0; i < blob_len(b); i++)
-               {
-                   if (i > 0)
-                       ga_concat(&ga, (char_u *)",");
-                   vim_snprintf((char *)numbuf, NUMBUFLEN, "0x%02X",
-                           (int)blob_get(b, i));
-                   ga_concat(&ga, numbuf);
-               }
-               ga_append(&ga, ']');
-               *tofree = ga.ga_data;
-               r = *tofree;
-           }
+           r = blob2string(tv->vval.v_blob, tofree, numbuf);
            break;
 
        case VAR_LIST:
@@ -8948,8 +8922,8 @@ read_viminfo_varlist(vir_T *virp, int writing)
            if (tab != NULL)
            {
                tv.v_type = type;
-               if (type == VAR_STRING || type == VAR_DICT ||
-                       type == VAR_LIST || type == VAR_BLOB)
+               if (type == VAR_STRING || type == VAR_DICT
+                       || type == VAR_LIST || type == VAR_BLOB)
                    tv.vval.v_string = viminfo_readstring(virp,
                                       (int)(tab - virp->vir_line + 1), TRUE);
 #ifdef FEAT_FLOAT
@@ -8958,7 +8932,7 @@ read_viminfo_varlist(vir_T *virp, int writing)
 #endif
                else
                    tv.vval.v_number = atol((char *)tab + 1);
-               if (type == VAR_DICT || type == VAR_LIST || type == VAR_BLOB)
+               if (type == VAR_DICT || type == VAR_LIST)
                {
                    typval_T *etv = eval_expr(tv.vval.v_string, NULL);
 
@@ -8973,6 +8947,20 @@ read_viminfo_varlist(vir_T *virp, int writing)
                        vim_free(etv);
                    }
                }
+               else if (type == VAR_BLOB)
+               {
+                   blob_T *blob = string2blob(tv.vval.v_string);
+
+                   if (blob == NULL)
+                       // Failed to parse back the blob, use it as a string.
+                       tv.v_type = VAR_STRING;
+                   else
+                   {
+                       vim_free(tv.vval.v_string);
+                       tv.v_type = VAR_BLOB;
+                       tv.vval.v_blob = blob;
+                   }
+               }
 
                /* when in a function use global variables */
                save_funccal(&funccal_entry);
@@ -9037,7 +9025,15 @@ write_viminfo_varlist(FILE *fp)
                                     continue;
                }
                fprintf(fp, "!%s\t%s\t", this_var->di_key, s);
-               p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
+               if (this_var->di_tv.v_type == VAR_SPECIAL)
+               {
+                   sprintf((char *)numbuf, "%ld",
+                                         (long)this_var->di_tv.vval.v_number);
+                   p = numbuf;
+                   tofree = NULL;
+               }
+               else
+                   p = echo_string(&this_var->di_tv, &tofree, numbuf, 0);
                if (p != NULL)
                    viminfo_writestring(fp, p);
                vim_free(tofree);
index 5e457ddaca9cac76c78c9275dd7dc6026811903c..1c645248634dcae8e6c6fda7f438893f9d118872 100644 (file)
@@ -10,4 +10,6 @@ void blob_set(blob_T *b, int idx, char_u c);
 int blob_equal(blob_T *b1, blob_T *b2);
 int read_blob(FILE *fd, blob_T *blob);
 int write_blob(FILE *fd, blob_T *blob);
+char_u *blob2string(blob_T *blob, char_u **tofree, char_u *numbuf);
+blob_T *string2blob(char_u *str);
 /* vim: set ft=c : */
index 6c0e533ab9657a4199d271f8b4f09a90155465d7..300f3a6556c327e7ee7e75d8576b8f5ac71eae47 100644 (file)
@@ -39,14 +39,36 @@ func Test_global_vars()
   " store a really long list, so line wrapping will occur in viminfo file
   let test_list = range(1,100)
   let g:MY_GLOBAL_LIST = test_list
+  let test_blob = 0z00112233445566778899aabbccddeeff
+  let g:MY_GLOBAL_BLOB = test_blob
+  let test_false = v:false
+  let g:MY_GLOBAL_FALSE = test_false
+  let test_true = v:true
+  let g:MY_GLOBAL_TRUE = test_true
+  let test_null = v:null
+  let g:MY_GLOBAL_NULL = test_null
+  let test_none = v:none
+  let g:MY_GLOBAL_NONE = test_none
+
   set viminfo='100,<50,s10,h,!,nviminfo
   wv! Xviminfo
+
   unlet g:MY_GLOBAL_DICT
   unlet g:MY_GLOBAL_LIST
+  unlet g:MY_GLOBAL_BLOB
+  unlet g:MY_GLOBAL_FALSE
+  unlet g:MY_GLOBAL_TRUE
+  unlet g:MY_GLOBAL_NULL
+  unlet g:MY_GLOBAL_NONE
 
   rv! Xviminfo
   call assert_equal(test_dict, g:MY_GLOBAL_DICT)
   call assert_equal(test_list, g:MY_GLOBAL_LIST)
+  call assert_equal(test_blob, g:MY_GLOBAL_BLOB)
+  call assert_equal(test_false, g:MY_GLOBAL_FALSE)
+  call assert_equal(test_true, g:MY_GLOBAL_TRUE)
+  call assert_equal(test_null, g:MY_GLOBAL_NULL)
+  call assert_equal(test_none, g:MY_GLOBAL_NONE)
 
   call delete('Xviminfo')
   set viminfo-=!
index d8681371f74ebeb9e43fbfa1a2a54031c8e56c63..a7ed174cf02f2118f9562ee8b9e618d0079ee667 100644 (file)
@@ -795,6 +795,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    741,
 /**/
     740,
 /**/