comparison src/eval.c @ 15454:1d2b5c016f17 v8.1.0735

patch 8.1.0735: cannot handle binary data commit https://github.com/vim/vim/commit/6e5ea8d2a995b32bbc5972edc4f827b959f2702f Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 12 22:47:31 2019 +0100 patch 8.1.0735: cannot handle binary data Problem: Cannot handle binary data. Solution: Add the Blob type. (Yasuhiro Matsumoto, closes https://github.com/vim/vim/issues/3638)
author Bram Moolenaar <Bram@vim.org>
date Sat, 12 Jan 2019 23:00:06 +0100
parents dada0b389d4f
children f01eb1aed348
comparison
equal deleted inserted replaced
15453:cdee6e827112 15454:1d2b5c016f17
76 { 76 {
77 int fi_semicolon; /* TRUE if ending in '; var]' */ 77 int fi_semicolon; /* TRUE if ending in '; var]' */
78 int fi_varcount; /* nr of variables in the list */ 78 int fi_varcount; /* nr of variables in the list */
79 listwatch_T fi_lw; /* keep an eye on the item used. */ 79 listwatch_T fi_lw; /* keep an eye on the item used. */
80 list_T *fi_list; /* list being used */ 80 list_T *fi_list; /* list being used */
81 int fi_bi; /* index of blob */
82 blob_T *fi_blob; /* blob being used */
81 } forinfo_T; 83 } forinfo_T;
82 84
83 85
84 /* 86 /*
85 * Array to hold the value of v: variables. 87 * Array to hold the value of v: variables.
185 {VV_NAME("t_float", VAR_NUMBER), VV_RO}, 187 {VV_NAME("t_float", VAR_NUMBER), VV_RO},
186 {VV_NAME("t_bool", VAR_NUMBER), VV_RO}, 188 {VV_NAME("t_bool", VAR_NUMBER), VV_RO},
187 {VV_NAME("t_none", VAR_NUMBER), VV_RO}, 189 {VV_NAME("t_none", VAR_NUMBER), VV_RO},
188 {VV_NAME("t_job", VAR_NUMBER), VV_RO}, 190 {VV_NAME("t_job", VAR_NUMBER), VV_RO},
189 {VV_NAME("t_channel", VAR_NUMBER), VV_RO}, 191 {VV_NAME("t_channel", VAR_NUMBER), VV_RO},
192 {VV_NAME("t_blob", VAR_NUMBER), VV_RO},
190 {VV_NAME("termrfgresp", VAR_STRING), VV_RO}, 193 {VV_NAME("termrfgresp", VAR_STRING), VV_RO},
191 {VV_NAME("termrbgresp", VAR_STRING), VV_RO}, 194 {VV_NAME("termrbgresp", VAR_STRING), VV_RO},
192 {VV_NAME("termu7resp", VAR_STRING), VV_RO}, 195 {VV_NAME("termu7resp", VAR_STRING), VV_RO},
193 {VV_NAME("termstyleresp", VAR_STRING), VV_RO}, 196 {VV_NAME("termstyleresp", VAR_STRING), VV_RO},
194 {VV_NAME("termblinkresp", VAR_STRING), VV_RO}, 197 {VV_NAME("termblinkresp", VAR_STRING), VV_RO},
200 #define vv_nr vv_di.di_tv.vval.v_number 203 #define vv_nr vv_di.di_tv.vval.v_number
201 #define vv_float vv_di.di_tv.vval.v_float 204 #define vv_float vv_di.di_tv.vval.v_float
202 #define vv_str vv_di.di_tv.vval.v_string 205 #define vv_str vv_di.di_tv.vval.v_string
203 #define vv_list vv_di.di_tv.vval.v_list 206 #define vv_list vv_di.di_tv.vval.v_list
204 #define vv_dict vv_di.di_tv.vval.v_dict 207 #define vv_dict vv_di.di_tv.vval.v_dict
208 #define vv_blob vv_di.di_tv.vval.v_blob
205 #define vv_tv vv_di.di_tv 209 #define vv_tv vv_di.di_tv
206 210
207 static dictitem_T vimvars_var; /* variable used for v: */ 211 static dictitem_T vimvars_var; /* variable used for v: */
208 #define vimvarht vimvardict.dv_hashtab 212 #define vimvarht vimvardict.dv_hashtab
209 213
336 set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT); 340 set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT);
337 set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL); 341 set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL);
338 set_vim_var_nr(VV_TYPE_NONE, VAR_TYPE_NONE); 342 set_vim_var_nr(VV_TYPE_NONE, VAR_TYPE_NONE);
339 set_vim_var_nr(VV_TYPE_JOB, VAR_TYPE_JOB); 343 set_vim_var_nr(VV_TYPE_JOB, VAR_TYPE_JOB);
340 set_vim_var_nr(VV_TYPE_CHANNEL, VAR_TYPE_CHANNEL); 344 set_vim_var_nr(VV_TYPE_CHANNEL, VAR_TYPE_CHANNEL);
345 set_vim_var_nr(VV_TYPE_BLOB, VAR_TYPE_BLOB);
341 346
342 set_reg_var(0); /* default for v:register is not 0 but '"' */ 347 set_reg_var(0); /* default for v:register is not 0 but '"' */
343 348
344 #ifdef EBCDIC 349 #ifdef EBCDIC
345 /* 350 /*
1916 var2.v_type = VAR_UNKNOWN; 1921 var2.v_type = VAR_UNKNOWN;
1917 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 1922 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT))
1918 { 1923 {
1919 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 1924 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
1920 && !(lp->ll_tv->v_type == VAR_DICT 1925 && !(lp->ll_tv->v_type == VAR_DICT
1921 && lp->ll_tv->vval.v_dict != NULL)) 1926 && lp->ll_tv->vval.v_dict != NULL)
1927 && !(lp->ll_tv->v_type == VAR_BLOB
1928 && lp->ll_tv->vval.v_blob != NULL))
1922 { 1929 {
1923 if (!quiet) 1930 if (!quiet)
1924 EMSG(_("E689: Can only index a List or Dictionary")); 1931 EMSG(_("E689: Can only index a List, Dictionary or Blob"));
1925 return NULL; 1932 return NULL;
1926 } 1933 }
1927 if (lp->ll_range) 1934 if (lp->ll_range)
1928 { 1935 {
1929 if (!quiet) 1936 if (!quiet)
1972 if (!quiet) 1979 if (!quiet)
1973 EMSG(_(e_dictrange)); 1980 EMSG(_(e_dictrange));
1974 clear_tv(&var1); 1981 clear_tv(&var1);
1975 return NULL; 1982 return NULL;
1976 } 1983 }
1977 if (rettv != NULL && (rettv->v_type != VAR_LIST 1984 if (rettv != NULL
1978 || rettv->vval.v_list == NULL)) 1985 && !(rettv->v_type == VAR_LIST
1986 || rettv->vval.v_list != NULL)
1987 && !(rettv->v_type == VAR_BLOB
1988 || rettv->vval.v_blob != NULL))
1979 { 1989 {
1980 if (!quiet) 1990 if (!quiet)
1981 EMSG(_("E709: [:] requires a List value")); 1991 EMSG(_("E709: [:] requires a List or Blob value"));
1982 clear_tv(&var1); 1992 clear_tv(&var1);
1983 return NULL; 1993 return NULL;
1984 } 1994 }
1985 p = skipwhite(p + 1); 1995 p = skipwhite(p + 1);
1986 if (*p == ']') 1996 if (*p == ']')
2095 } 2105 }
2096 2106
2097 clear_tv(&var1); 2107 clear_tv(&var1);
2098 lp->ll_tv = &lp->ll_di->di_tv; 2108 lp->ll_tv = &lp->ll_di->di_tv;
2099 } 2109 }
2110 else if (lp->ll_tv->v_type == VAR_BLOB)
2111 {
2112 /*
2113 * Get the number and item for the only or first index of the List.
2114 */
2115 if (empty1)
2116 lp->ll_n1 = 0;
2117 else
2118 // is number or string
2119 lp->ll_n1 = (long)tv_get_number(&var1);
2120 clear_tv(&var1);
2121
2122 if (lp->ll_n1 < 0
2123 || lp->ll_n1 > blob_len(lp->ll_tv->vval.v_blob))
2124 {
2125 if (!quiet)
2126 EMSGN(_(e_listidx), lp->ll_n1);
2127 return NULL;
2128 }
2129 if (lp->ll_range && !lp->ll_empty2)
2130 {
2131 lp->ll_n2 = (long)tv_get_number(&var2);
2132 clear_tv(&var2);
2133 }
2134 lp->ll_blob = lp->ll_tv->vval.v_blob;
2135 lp->ll_tv = NULL;
2136 }
2100 else 2137 else
2101 { 2138 {
2102 /* 2139 /*
2103 * Get the number and item for the only or first index of the List. 2140 * Get the number and item for the only or first index of the List.
2104 */ 2141 */
2199 2236
2200 if (lp->ll_tv == NULL) 2237 if (lp->ll_tv == NULL)
2201 { 2238 {
2202 cc = *endp; 2239 cc = *endp;
2203 *endp = NUL; 2240 *endp = NUL;
2204 if (op != NULL && *op != '=') 2241 if (lp->ll_blob != NULL)
2242 {
2243 int error = FALSE, val;
2244 if (op != NULL && *op != '=')
2245 {
2246 EMSG2(_(e_letwrong), op);
2247 return;
2248 }
2249
2250 if (lp->ll_range && rettv->v_type == VAR_BLOB)
2251 {
2252 int i;
2253
2254 if (blob_len(rettv->vval.v_blob) != blob_len(lp->ll_blob))
2255 {
2256 EMSG(_("E972: Blob value has more items than target"));
2257 return;
2258 }
2259
2260 for (i = lp->ll_n1; i <= lp->ll_n2; i++)
2261 blob_set(lp->ll_blob, i,
2262 blob_get(rettv->vval.v_blob, i));
2263 }
2264 else
2265 {
2266 val = (int)tv_get_number_chk(rettv, &error);
2267 if (!error)
2268 {
2269 garray_T *gap = &lp->ll_blob->bv_ga;
2270
2271 // Allow for appending a byte. Setting a byte beyond
2272 // the end is an error otherwise.
2273 if (lp->ll_n1 < gap->ga_len
2274 || (lp->ll_n1 == gap->ga_len
2275 && ga_grow(&lp->ll_blob->bv_ga, 1) == OK))
2276 {
2277 blob_set(lp->ll_blob, lp->ll_n1, val);
2278 if (lp->ll_n1 == gap->ga_len)
2279 ++gap->ga_len;
2280 }
2281 else
2282 EMSG(_(e_invrange));
2283 }
2284 }
2285 }
2286 else if (op != NULL && *op != '=')
2205 { 2287 {
2206 typval_T tv; 2288 typval_T tv;
2207 2289
2208 /* handle +=, -= and .= */ 2290 /* handle +=, -= and .= */
2209 di = NULL; 2291 di = NULL;
2349 case VAR_PARTIAL: 2431 case VAR_PARTIAL:
2350 case VAR_SPECIAL: 2432 case VAR_SPECIAL:
2351 case VAR_JOB: 2433 case VAR_JOB:
2352 case VAR_CHANNEL: 2434 case VAR_CHANNEL:
2353 break; 2435 break;
2436
2437 case VAR_BLOB:
2438 if (*op != '+' || tv2->v_type != VAR_BLOB)
2439 break;
2440 // BLOB += BLOB
2441 if (tv1->vval.v_blob != NULL && tv2->vval.v_blob != NULL)
2442 {
2443 blob_T *b1 = tv1->vval.v_blob;
2444 blob_T *b2 = tv2->vval.v_blob;
2445 int i, len = blob_len(b2);
2446 for (i = 0; i < len; i++)
2447 ga_append(&b1->bv_ga, blob_get(b2, i));
2448 }
2449 return OK;
2354 2450
2355 case VAR_LIST: 2451 case VAR_LIST:
2356 if (*op != '+' || tv2->v_type != VAR_LIST) 2452 if (*op != '+' || tv2->v_type != VAR_LIST)
2357 break; 2453 break;
2358 /* List += List */ 2454 /* List += List */
2449 { 2545 {
2450 forinfo_T *fi; 2546 forinfo_T *fi;
2451 char_u *expr; 2547 char_u *expr;
2452 typval_T tv; 2548 typval_T tv;
2453 list_T *l; 2549 list_T *l;
2550 blob_T *b;
2454 2551
2455 *errp = TRUE; /* default: there is an error */ 2552 *errp = TRUE; /* default: there is an error */
2456 2553
2457 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2554 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T));
2458 if (fi == NULL) 2555 if (fi == NULL)
2474 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2571 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK)
2475 { 2572 {
2476 *errp = FALSE; 2573 *errp = FALSE;
2477 if (!skip) 2574 if (!skip)
2478 { 2575 {
2479 l = tv.vval.v_list; 2576 if (tv.v_type == VAR_LIST)
2480 if (tv.v_type != VAR_LIST) 2577 {
2578 l = tv.vval.v_list;
2579 if (l == NULL)
2580 {
2581 // a null list is like an empty list: do nothing
2582 clear_tv(&tv);
2583 }
2584 else
2585 {
2586 // No need to increment the refcount, it's already set for
2587 // the list being used in "tv".
2588 fi->fi_list = l;
2589 list_add_watch(l, &fi->fi_lw);
2590 fi->fi_lw.lw_item = l->lv_first;
2591 }
2592 }
2593 else if (tv.v_type == VAR_BLOB)
2594 {
2595 b = tv.vval.v_blob;
2596 if (b == NULL)
2597 clear_tv(&tv);
2598 else
2599 {
2600 fi->fi_blob = b;
2601 fi->fi_bi = 0;
2602 }
2603 }
2604 else
2481 { 2605 {
2482 EMSG(_(e_listreq)); 2606 EMSG(_(e_listreq));
2483 clear_tv(&tv); 2607 clear_tv(&tv);
2484 }
2485 else if (l == NULL)
2486 {
2487 /* a null list is like an empty list: do nothing */
2488 clear_tv(&tv);
2489 }
2490 else
2491 {
2492 /* No need to increment the refcount, it's already set for the
2493 * list being used in "tv". */
2494 fi->fi_list = l;
2495 list_add_watch(l, &fi->fi_lw);
2496 fi->fi_lw.lw_item = l->lv_first;
2497 } 2608 }
2498 } 2609 }
2499 } 2610 }
2500 if (skip) 2611 if (skip)
2501 --emsg_skip; 2612 --emsg_skip;
2513 next_for_item(void *fi_void, char_u *arg) 2624 next_for_item(void *fi_void, char_u *arg)
2514 { 2625 {
2515 forinfo_T *fi = (forinfo_T *)fi_void; 2626 forinfo_T *fi = (forinfo_T *)fi_void;
2516 int result; 2627 int result;
2517 listitem_T *item; 2628 listitem_T *item;
2629
2630 if (fi->fi_blob != NULL)
2631 {
2632 typval_T tv;
2633
2634 if (fi->fi_bi >= blob_len(fi->fi_blob))
2635 return FALSE;
2636 tv.v_type = VAR_NUMBER;
2637 tv.v_lock = VAR_FIXED;
2638 tv.vval.v_number = blob_get(fi->fi_blob, fi->fi_bi);
2639 ++fi->fi_bi;
2640 return ex_let_vars(arg, &tv, TRUE,
2641 fi->fi_semicolon, fi->fi_varcount, NULL) == OK;
2642 }
2518 2643
2519 item = fi->fi_lw.lw_item; 2644 item = fi->fi_lw.lw_item;
2520 if (item == NULL) 2645 if (item == NULL)
2521 result = FALSE; 2646 result = FALSE;
2522 else 2647 else
2953 { 3078 {
2954 static int recurse = 0; 3079 static int recurse = 0;
2955 list_T *l; 3080 list_T *l;
2956 listitem_T *li; 3081 listitem_T *li;
2957 dict_T *d; 3082 dict_T *d;
3083 blob_T *b;
2958 hashitem_T *hi; 3084 hashitem_T *hi;
2959 int todo; 3085 int todo;
2960 3086
2961 if (recurse >= DICT_MAXNEST) 3087 if (recurse >= DICT_MAXNEST)
2962 { 3088 {
2984 case VAR_SPECIAL: 3110 case VAR_SPECIAL:
2985 case VAR_JOB: 3111 case VAR_JOB:
2986 case VAR_CHANNEL: 3112 case VAR_CHANNEL:
2987 break; 3113 break;
2988 3114
3115 case VAR_BLOB:
3116 if ((b = tv->vval.v_blob) != NULL)
3117 {
3118 if (lock)
3119 b->bv_lock |= VAR_LOCKED;
3120 else
3121 b->bv_lock &= ~VAR_LOCKED;
3122 }
3123 break;
2989 case VAR_LIST: 3124 case VAR_LIST:
2990 if ((l = tv->vval.v_list) != NULL) 3125 if ((l = tv->vval.v_list) != NULL)
2991 { 3126 {
2992 if (lock) 3127 if (lock)
2993 l->lv_lock |= VAR_LOCKED; 3128 l->lv_lock |= VAR_LOCKED;
3607 { 3742 {
3608 op = **arg; 3743 op = **arg;
3609 if (op != '+' && op != '-' && op != '.') 3744 if (op != '+' && op != '-' && op != '.')
3610 break; 3745 break;
3611 3746
3612 if ((op != '+' || rettv->v_type != VAR_LIST) 3747 if ((op != '+' || (rettv->v_type != VAR_LIST
3748 && rettv->v_type != VAR_BLOB))
3613 #ifdef FEAT_FLOAT 3749 #ifdef FEAT_FLOAT
3614 && (op == '.' || rettv->v_type != VAR_FLOAT) 3750 && (op == '.' || rettv->v_type != VAR_FLOAT)
3615 #endif 3751 #endif
3616 ) 3752 )
3617 { 3753 {
3656 } 3792 }
3657 p = concat_str(s1, s2); 3793 p = concat_str(s1, s2);
3658 clear_tv(rettv); 3794 clear_tv(rettv);
3659 rettv->v_type = VAR_STRING; 3795 rettv->v_type = VAR_STRING;
3660 rettv->vval.v_string = p; 3796 rettv->vval.v_string = p;
3797 }
3798 else if (op == '+' && rettv->v_type == VAR_BLOB
3799 && var2.v_type == VAR_BLOB)
3800 {
3801 blob_T *b1 = rettv->vval.v_blob;
3802 blob_T *b2 = var2.vval.v_blob;
3803 blob_T *b = blob_alloc();
3804 int i;
3805
3806 if (b != NULL)
3807 {
3808 for (i = 0; i < blob_len(b1); i++)
3809 ga_append(&b->bv_ga, blob_get(b1, i));
3810 for (i = 0; i < blob_len(b2); i++)
3811 ga_append(&b->bv_ga, blob_get(b2, i));
3812
3813 clear_tv(rettv);
3814 rettv_blob_set(rettv, b);
3815 }
3661 } 3816 }
3662 else if (op == '+' && rettv->v_type == VAR_LIST 3817 else if (op == '+' && rettv->v_type == VAR_LIST
3663 && var2.v_type == VAR_LIST) 3818 && var2.v_type == VAR_LIST)
3664 { 3819 {
3665 /* concatenate Lists */ 3820 /* concatenate Lists */
3919 } 4074 }
3920 4075
3921 /* 4076 /*
3922 * Handle sixth level expression: 4077 * Handle sixth level expression:
3923 * number number constant 4078 * number number constant
4079 * 0zFFFFFFFF Blob constant
3924 * "string" string constant 4080 * "string" string constant
3925 * 'string' literal string constant 4081 * 'string' literal string constant
3926 * &option-name option value 4082 * &option-name option value
3927 * @r register contents 4083 * @r register contents
3928 * identifier variable value 4084 * identifier variable value
4025 rettv->vval.v_float = f; 4181 rettv->vval.v_float = f;
4026 } 4182 }
4027 } 4183 }
4028 else 4184 else
4029 #endif 4185 #endif
4186 if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z'))
4030 { 4187 {
4188 char_u *bp;
4189 blob_T *blob;
4190
4191 // Blob constant: 0z0123456789abcdef
4192 if (evaluate)
4193 blob = blob_alloc();
4194 for (bp = *arg + 2; vim_isxdigit(bp[0]); bp += 2)
4195 {
4196 if (!vim_isxdigit(bp[1]))
4197 {
4198 EMSG(_("E973: Blob literal should have an even number of hex characters'"));
4199 vim_free(blob);
4200 ret = FAIL;
4201 break;
4202 }
4203 if (blob != NULL)
4204 ga_append(&blob->bv_ga,
4205 (hex2nr(*bp) << 4) + hex2nr(*(bp+1)));
4206 }
4207 if (blob != NULL)
4208 {
4209 ++blob->bv_refcount;
4210 rettv->v_type = VAR_BLOB;
4211 rettv->vval.v_blob = blob;
4212 }
4213 *arg = bp;
4214 }
4215 else
4216 {
4217 // decimal, hex or octal number
4031 vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0); 4218 vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0);
4032 *arg += len; 4219 *arg += len;
4033 if (evaluate) 4220 if (evaluate)
4034 { 4221 {
4035 rettv->v_type = VAR_NUMBER; 4222 rettv->v_type = VAR_NUMBER;
4261 int evaluate, 4448 int evaluate,
4262 int verbose) /* give error messages */ 4449 int verbose) /* give error messages */
4263 { 4450 {
4264 int empty1 = FALSE, empty2 = FALSE; 4451 int empty1 = FALSE, empty2 = FALSE;
4265 typval_T var1, var2; 4452 typval_T var1, var2;
4453 long i;
4266 long n1, n2 = 0; 4454 long n1, n2 = 0;
4267 long len = -1; 4455 long len = -1;
4268 int range = FALSE; 4456 int range = FALSE;
4269 char_u *s; 4457 char_u *s;
4270 char_u *key = NULL; 4458 char_u *key = NULL;
4295 4483
4296 case VAR_STRING: 4484 case VAR_STRING:
4297 case VAR_NUMBER: 4485 case VAR_NUMBER:
4298 case VAR_LIST: 4486 case VAR_LIST:
4299 case VAR_DICT: 4487 case VAR_DICT:
4488 case VAR_BLOB:
4300 break; 4489 break;
4301 } 4490 }
4302 4491
4303 init_tv(&var1); 4492 init_tv(&var1);
4304 init_tv(&var2); 4493 init_tv(&var2);
4437 clear_tv(rettv); 4626 clear_tv(rettv);
4438 rettv->v_type = VAR_STRING; 4627 rettv->v_type = VAR_STRING;
4439 rettv->vval.v_string = s; 4628 rettv->vval.v_string = s;
4440 break; 4629 break;
4441 4630
4631 case VAR_BLOB:
4632 len = blob_len(rettv->vval.v_blob);
4633 if (range)
4634 {
4635 // The resulting variable is a substring. If the indexes
4636 // are out of range the result is empty.
4637 if (n1 < 0)
4638 {
4639 n1 = len + n1;
4640 if (n1 < 0)
4641 n1 = 0;
4642 }
4643 if (n2 < 0)
4644 n2 = len + n2;
4645 else if (n2 >= len)
4646 n2 = len - 1;
4647 if (n1 >= len || n2 < 0 || n1 > n2)
4648 {
4649 clear_tv(rettv);
4650 rettv->v_type = VAR_BLOB;
4651 rettv->vval.v_blob = NULL;
4652 }
4653 else
4654 {
4655 blob_T *blob = blob_alloc();
4656
4657 if (blob != NULL)
4658 {
4659 if (ga_grow(&blob->bv_ga, n2 - n1 + 1) == FAIL)
4660 {
4661 blob_free(blob);
4662 return FAIL;
4663 }
4664 blob->bv_ga.ga_len = n2 - n1 + 1;
4665 for (i = n1; i <= n2; i++)
4666 blob_set(blob, i - n1,
4667 blob_get(rettv->vval.v_blob, i));
4668
4669 clear_tv(rettv);
4670 rettv_blob_set(rettv, blob);
4671 }
4672 }
4673 }
4674 else
4675 {
4676 // The resulting variable is a string of a single
4677 // character. If the index is too big or negative the
4678 // result is empty.
4679 if (n1 < len && n1 >= 0)
4680 {
4681 int v = (int)blob_get(rettv->vval.v_blob, n1);
4682
4683 clear_tv(rettv);
4684 rettv->v_type = VAR_NUMBER;
4685 rettv->vval.v_number = v;
4686 }
4687 else
4688 EMSGN(_(e_blobidx), n1);
4689 }
4690 break;
4691
4442 case VAR_LIST: 4692 case VAR_LIST:
4443 len = list_len(rettv->vval.v_list); 4693 len = list_len(rettv->vval.v_list);
4444 if (n1 < 0) 4694 if (n1 < 0)
4445 n1 = len + n1; 4695 n1 = len + n1;
4446 if (!empty1 && (n1 < 0 || n1 >= len)) 4696 if (!empty1 && (n1 < 0 || n1 >= len))
4968 ++recursive_cnt; 5218 ++recursive_cnt;
4969 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE); 5219 r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
4970 --recursive_cnt; 5220 --recursive_cnt;
4971 return r; 5221 return r;
4972 5222
5223 case VAR_BLOB:
5224 return blob_equal(tv1->vval.v_blob, tv2->vval.v_blob);
5225
4973 case VAR_NUMBER: 5226 case VAR_NUMBER:
4974 return tv1->vval.v_number == tv2->vval.v_number; 5227 return tv1->vval.v_number == tv2->vval.v_number;
4975 5228
4976 case VAR_STRING: 5229 case VAR_STRING:
4977 s1 = tv_get_string_buf(tv1, buf1); 5230 s1 = tv_get_string_buf(tv1, buf1);
5600 *tofree = ga.ga_data; 5853 *tofree = ga.ga_data;
5601 r = *tofree; 5854 r = *tofree;
5602 break; 5855 break;
5603 } 5856 }
5604 5857
5858 case VAR_BLOB:
5859 if (tv->vval.v_blob == NULL)
5860 {
5861 *tofree = NULL;
5862 r = (char_u *)"[]";
5863 }
5864 else
5865 {
5866 blob_T *b;
5867 int i;
5868 garray_T ga;
5869
5870 // Store bytes in the growarray.
5871 ga_init2(&ga, 1, 4000);
5872 b = tv->vval.v_blob;
5873 ga_append(&ga, '[');
5874 for (i = 0; i < blob_len(b); i++)
5875 {
5876 if (i > 0)
5877 ga_concat(&ga, (char_u *)",");
5878 vim_snprintf((char *)numbuf, NUMBUFLEN, "0x%02X",
5879 (int)blob_get(b, i));
5880 ga_concat(&ga, numbuf);
5881 }
5882 ga_append(&ga, ']');
5883 *tofree = ga.ga_data;
5884 r = *tofree;
5885 }
5886 break;
5887
5605 case VAR_LIST: 5888 case VAR_LIST:
5606 if (tv->vval.v_list == NULL) 5889 if (tv->vval.v_list == NULL)
5607 { 5890 {
5608 *tofree = NULL; 5891 *tofree = NULL;
5609 r = NULL; 5892 r = NULL;
6838 case VAR_STRING: 7121 case VAR_STRING:
6839 vim_free(varp->vval.v_string); 7122 vim_free(varp->vval.v_string);
6840 break; 7123 break;
6841 case VAR_PARTIAL: 7124 case VAR_PARTIAL:
6842 partial_unref(varp->vval.v_partial); 7125 partial_unref(varp->vval.v_partial);
7126 break;
7127 case VAR_BLOB:
7128 blob_unref(varp->vval.v_blob);
6843 break; 7129 break;
6844 case VAR_LIST: 7130 case VAR_LIST:
6845 list_unref(varp->vval.v_list); 7131 list_unref(varp->vval.v_list);
6846 break; 7132 break;
6847 case VAR_DICT: 7133 case VAR_DICT:
6884 VIM_CLEAR(varp->vval.v_string); 7170 VIM_CLEAR(varp->vval.v_string);
6885 break; 7171 break;
6886 case VAR_PARTIAL: 7172 case VAR_PARTIAL:
6887 partial_unref(varp->vval.v_partial); 7173 partial_unref(varp->vval.v_partial);
6888 varp->vval.v_partial = NULL; 7174 varp->vval.v_partial = NULL;
7175 break;
7176 case VAR_BLOB:
7177 blob_unref(varp->vval.v_blob);
7178 varp->vval.v_blob = NULL;
6889 break; 7179 break;
6890 case VAR_LIST: 7180 case VAR_LIST:
6891 list_unref(varp->vval.v_list); 7181 list_unref(varp->vval.v_list);
6892 varp->vval.v_list = NULL; 7182 varp->vval.v_list = NULL;
6893 break; 7183 break;
6988 case VAR_CHANNEL: 7278 case VAR_CHANNEL:
6989 #ifdef FEAT_JOB_CHANNEL 7279 #ifdef FEAT_JOB_CHANNEL
6990 EMSG(_("E913: Using a Channel as a Number")); 7280 EMSG(_("E913: Using a Channel as a Number"));
6991 break; 7281 break;
6992 #endif 7282 #endif
7283 case VAR_BLOB:
7284 EMSG(_("E974: Using a Blob as a Number"));
7285 break;
6993 case VAR_UNKNOWN: 7286 case VAR_UNKNOWN:
6994 internal_error("tv_get_number(UNKNOWN)"); 7287 internal_error("tv_get_number(UNKNOWN)");
6995 break; 7288 break;
6996 } 7289 }
6997 if (denote == NULL) /* useful for values that must be unsigned */ 7290 if (denote == NULL) /* useful for values that must be unsigned */
7035 case VAR_CHANNEL: 7328 case VAR_CHANNEL:
7036 # ifdef FEAT_JOB_CHANNEL 7329 # ifdef FEAT_JOB_CHANNEL
7037 EMSG(_("E914: Using a Channel as a Float")); 7330 EMSG(_("E914: Using a Channel as a Float"));
7038 break; 7331 break;
7039 # endif 7332 # endif
7333 case VAR_BLOB:
7334 EMSG(_("E975: Using a Blob as a Float"));
7335 break;
7040 case VAR_UNKNOWN: 7336 case VAR_UNKNOWN:
7041 internal_error("tv_get_float(UNKNOWN)"); 7337 internal_error("tv_get_float(UNKNOWN)");
7042 break; 7338 break;
7043 } 7339 }
7044 return 0; 7340 return 0;
7111 return varp->vval.v_string; 7407 return varp->vval.v_string;
7112 return (char_u *)""; 7408 return (char_u *)"";
7113 case VAR_SPECIAL: 7409 case VAR_SPECIAL:
7114 STRCPY(buf, get_var_special_name(varp->vval.v_number)); 7410 STRCPY(buf, get_var_special_name(varp->vval.v_number));
7115 return buf; 7411 return buf;
7412 case VAR_BLOB:
7413 EMSG(_("E976: using Blob as a String"));
7414 break;
7116 case VAR_JOB: 7415 case VAR_JOB:
7117 #ifdef FEAT_JOB_CHANNEL 7416 #ifdef FEAT_JOB_CHANNEL
7118 { 7417 {
7119 job_T *job = varp->vval.v_job; 7418 job_T *job = varp->vval.v_job;
7120 char *status; 7419 char *status;
7803 { 8102 {
7804 to->vval.v_partial = from->vval.v_partial; 8103 to->vval.v_partial = from->vval.v_partial;
7805 ++to->vval.v_partial->pt_refcount; 8104 ++to->vval.v_partial->pt_refcount;
7806 } 8105 }
7807 break; 8106 break;
8107 case VAR_BLOB:
8108 if (from->vval.v_blob == NULL)
8109 to->vval.v_blob = NULL;
8110 else
8111 {
8112 to->vval.v_blob = from->vval.v_blob;
8113 ++to->vval.v_blob->bv_refcount;
8114 }
8115 break;
7808 case VAR_LIST: 8116 case VAR_LIST:
7809 if (from->vval.v_list == NULL) 8117 if (from->vval.v_list == NULL)
7810 to->vval.v_list = NULL; 8118 to->vval.v_list = NULL;
7811 else 8119 else
7812 { 8120 {
7861 case VAR_FUNC: 8169 case VAR_FUNC:
7862 case VAR_PARTIAL: 8170 case VAR_PARTIAL:
7863 case VAR_SPECIAL: 8171 case VAR_SPECIAL:
7864 case VAR_JOB: 8172 case VAR_JOB:
7865 case VAR_CHANNEL: 8173 case VAR_CHANNEL:
8174 case VAR_BLOB:
7866 copy_tv(from, to); 8175 copy_tv(from, to);
7867 break; 8176 break;
7868 case VAR_LIST: 8177 case VAR_LIST:
7869 to->v_type = VAR_LIST; 8178 to->v_type = VAR_LIST;
7870 to->v_lock = 0; 8179 to->v_lock = 0;
8599 #ifdef FEAT_FLOAT 8908 #ifdef FEAT_FLOAT
8600 case 'F': type = VAR_FLOAT; break; 8909 case 'F': type = VAR_FLOAT; break;
8601 #endif 8910 #endif
8602 case 'D': type = VAR_DICT; break; 8911 case 'D': type = VAR_DICT; break;
8603 case 'L': type = VAR_LIST; break; 8912 case 'L': type = VAR_LIST; break;
8913 case 'B': type = VAR_BLOB; break;
8604 case 'X': type = VAR_SPECIAL; break; 8914 case 'X': type = VAR_SPECIAL; break;
8605 } 8915 }
8606 8916
8607 tab = vim_strchr(tab, '\t'); 8917 tab = vim_strchr(tab, '\t');
8608 if (tab != NULL) 8918 if (tab != NULL)
8609 { 8919 {
8610 tv.v_type = type; 8920 tv.v_type = type;
8611 if (type == VAR_STRING || type == VAR_DICT || type == VAR_LIST) 8921 if (type == VAR_STRING || type == VAR_DICT ||
8922 type == VAR_LIST || type == VAR_BLOB)
8612 tv.vval.v_string = viminfo_readstring(virp, 8923 tv.vval.v_string = viminfo_readstring(virp,
8613 (int)(tab - virp->vir_line + 1), TRUE); 8924 (int)(tab - virp->vir_line + 1), TRUE);
8614 #ifdef FEAT_FLOAT 8925 #ifdef FEAT_FLOAT
8615 else if (type == VAR_FLOAT) 8926 else if (type == VAR_FLOAT)
8616 (void)string2float(tab + 1, &tv.vval.v_float); 8927 (void)string2float(tab + 1, &tv.vval.v_float);
8617 #endif 8928 #endif
8618 else 8929 else
8619 tv.vval.v_number = atol((char *)tab + 1); 8930 tv.vval.v_number = atol((char *)tab + 1);
8620 if (type == VAR_DICT || type == VAR_LIST) 8931 if (type == VAR_DICT || type == VAR_LIST || type == VAR_BLOB)
8621 { 8932 {
8622 typval_T *etv = eval_expr(tv.vval.v_string, NULL); 8933 typval_T *etv = eval_expr(tv.vval.v_string, NULL);
8623 8934
8624 if (etv == NULL) 8935 if (etv == NULL)
8625 /* Failed to parse back the dict or list, use it as a 8936 /* Failed to parse back the dict or list, use it as a
8638 set_var(virp->vir_line + 1, &tv, FALSE); 8949 set_var(virp->vir_line + 1, &tv, FALSE);
8639 restore_funccal(); 8950 restore_funccal();
8640 8951
8641 if (tv.v_type == VAR_STRING) 8952 if (tv.v_type == VAR_STRING)
8642 vim_free(tv.vval.v_string); 8953 vim_free(tv.vval.v_string);
8643 else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST) 8954 else if (tv.v_type == VAR_DICT || tv.v_type == VAR_LIST ||
8955 tv.v_type == VAR_BLOB)
8644 clear_tv(&tv); 8956 clear_tv(&tv);
8645 } 8957 }
8646 } 8958 }
8647 } 8959 }
8648 8960
8682 case VAR_STRING: s = "STR"; break; 8994 case VAR_STRING: s = "STR"; break;
8683 case VAR_NUMBER: s = "NUM"; break; 8995 case VAR_NUMBER: s = "NUM"; break;
8684 case VAR_FLOAT: s = "FLO"; break; 8996 case VAR_FLOAT: s = "FLO"; break;
8685 case VAR_DICT: s = "DIC"; break; 8997 case VAR_DICT: s = "DIC"; break;
8686 case VAR_LIST: s = "LIS"; break; 8998 case VAR_LIST: s = "LIS"; break;
8999 case VAR_BLOB: s = "BLO"; break;
8687 case VAR_SPECIAL: s = "XPL"; break; 9000 case VAR_SPECIAL: s = "XPL"; break;
8688 9001
8689 case VAR_UNKNOWN: 9002 case VAR_UNKNOWN:
8690 case VAR_FUNC: 9003 case VAR_FUNC:
8691 case VAR_PARTIAL: 9004 case VAR_PARTIAL:
9247 if (type_is && typ1->v_type != typ2->v_type) 9560 if (type_is && typ1->v_type != typ2->v_type)
9248 { 9561 {
9249 /* For "is" a different type always means FALSE, for "notis" 9562 /* For "is" a different type always means FALSE, for "notis"
9250 * it means TRUE. */ 9563 * it means TRUE. */
9251 n1 = (type == TYPE_NEQUAL); 9564 n1 = (type == TYPE_NEQUAL);
9565 }
9566 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB)
9567 {
9568 if (type_is)
9569 {
9570 n1 = (typ1->v_type == typ2->v_type
9571 && typ1->vval.v_blob == typ2->vval.v_blob);
9572 if (type == TYPE_NEQUAL)
9573 n1 = !n1;
9574 }
9575 else if (typ1->v_type != typ2->v_type
9576 || (type != TYPE_EQUAL && type != TYPE_NEQUAL))
9577 {
9578 if (typ1->v_type != typ2->v_type)
9579 EMSG(_("E977: Can only compare Blob with Blob"));
9580 else
9581 EMSG(_(e_invalblob));
9582 clear_tv(typ1);
9583 return FAIL;
9584 }
9585 else
9586 {
9587 // Compare two Blobs for being equal or unequal.
9588 n1 = blob_equal(typ1->vval.v_blob, typ2->vval.v_blob);
9589 if (type == TYPE_NEQUAL)
9590 n1 = !n1;
9591 }
9252 } 9592 }
9253 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) 9593 else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST)
9254 { 9594 {
9255 if (type_is) 9595 if (type_is)
9256 { 9596 {
10276 hashtab_T *ht; 10616 hashtab_T *ht;
10277 hashitem_T *hi; 10617 hashitem_T *hi;
10278 dict_T *d = NULL; 10618 dict_T *d = NULL;
10279 typval_T save_val; 10619 typval_T save_val;
10280 typval_T save_key; 10620 typval_T save_key;
10621 blob_T *b = NULL;
10281 int rem; 10622 int rem;
10282 int todo; 10623 int todo;
10283 char_u *ermsg = (char_u *)(map ? "map()" : "filter()"); 10624 char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
10284 char_u *arg_errmsg = (char_u *)(map ? N_("map() argument") 10625 char_u *arg_errmsg = (char_u *)(map ? N_("map() argument")
10285 : N_("filter() argument")); 10626 : N_("filter() argument"));
10286 int save_did_emsg; 10627 int save_did_emsg;
10287 int idx = 0; 10628 int idx = 0;
10288 10629
10289 if (argvars[0].v_type == VAR_LIST) 10630 if (argvars[0].v_type == VAR_BLOB)
10631 {
10632 if ((b = argvars[0].vval.v_blob) == NULL)
10633 return;
10634 }
10635 else if (argvars[0].v_type == VAR_LIST)
10290 { 10636 {
10291 if ((l = argvars[0].vval.v_list) == NULL 10637 if ((l = argvars[0].vval.v_list) == NULL
10292 || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TRUE))) 10638 || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TRUE)))
10293 return; 10639 return;
10294 } 10640 }
10351 } 10697 }
10352 } 10698 }
10353 } 10699 }
10354 hash_unlock(ht); 10700 hash_unlock(ht);
10355 } 10701 }
10702 else if (argvars[0].v_type == VAR_BLOB)
10703 {
10704 int i;
10705 typval_T tv;
10706
10707 vimvars[VV_KEY].vv_type = VAR_NUMBER;
10708 for (i = 0; i < b->bv_ga.ga_len; i++)
10709 {
10710 tv.v_type = VAR_NUMBER;
10711 tv.vval.v_number = blob_get(b, i);
10712 vimvars[VV_KEY].vv_nr = idx;
10713 if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg)
10714 break;
10715 if (tv.v_type != VAR_NUMBER)
10716 {
10717 EMSG(_(e_invalblob));
10718 return;
10719 }
10720 tv.v_type = VAR_NUMBER;
10721 blob_set(b, i, tv.vval.v_number);
10722 if (!map && rem)
10723 {
10724 char_u *p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data;
10725
10726 mch_memmove(p + idx, p + i + 1,
10727 (size_t)b->bv_ga.ga_len - i - 1);
10728 --b->bv_ga.ga_len;
10729 --i;
10730 }
10731 }
10732 }
10356 else 10733 else
10357 { 10734 {
10358 vimvars[VV_KEY].vv_type = VAR_NUMBER; 10735 vimvars[VV_KEY].vv_type = VAR_NUMBER;
10359 10736
10360 for (li = l->lv_first; li != NULL; li = nli) 10737 for (li = l->lv_first; li != NULL; li = nli)