diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.c | 4 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 31 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 4 | ||||
-rw-r--r-- | src/nvim/testdir/test_blob.vim | 12 |
4 files changed, 48 insertions, 3 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index b81384266c..0fbf31a8cd 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1613,7 +1613,7 @@ void set_var_lval(lval_T *lp, char *endp, typval_T *rettv, int copy, const bool lp->ll_n2 = tv_blob_len(lp->ll_blob) - 1; } - if (tv_blob_set_range(lp->ll_blob, lp->ll_n1, lp->ll_n2, rettv) == FAIL) { + if (tv_blob_set_range(lp->ll_blob, (int)lp->ll_n1, (int)lp->ll_n2, rettv) == FAIL) { return; } } else { @@ -4938,6 +4938,8 @@ theend: return retval; } +/// "function()" function +/// "funcref()" function void common_function(typval_T *argvars, typval_T *rettv, bool is_funcref) { char *s; diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 5da6233e38..4208c5ca46 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -5976,6 +5976,37 @@ static void f_repeat(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) while (n-- > 0) { tv_list_extend(rettv->vval.v_list, argvars[0].vval.v_list, NULL); } + } else if (argvars[0].v_type == VAR_BLOB) { + tv_blob_alloc_ret(rettv); + if (argvars[0].vval.v_blob == NULL || n <= 0) { + return; + } + + const int slen = argvars[0].vval.v_blob->bv_ga.ga_len; + const int len = (int)(slen * n); + if (len <= 0) { + return; + } + + ga_grow(&rettv->vval.v_blob->bv_ga, len); + + rettv->vval.v_blob->bv_ga.ga_len = len; + + int i; + for (i = 0; i < slen; i++) { + if (tv_blob_get(argvars[0].vval.v_blob, i) != 0) { + break; + } + } + + if (i == slen) { + // No need to copy since all bytes are already zero + return; + } + + for (i = 0; i < n; i++) { + tv_blob_set_range(rettv->vval.v_blob, i * slen, (i + 1) * slen - 1, argvars); + } } else { rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 6037536548..7d49049b0c 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2743,14 +2743,14 @@ int tv_blob_check_range(int bloblen, varnumber_T n1, varnumber_T n2, bool quiet) /// Set bytes "n1" to "n2" (inclusive) in "dest" to the value of "src". /// Caller must make sure "src" is a blob. /// Returns FAIL if the number of bytes does not match. -int tv_blob_set_range(blob_T *dest, long n1, long n2, typval_T *src) +int tv_blob_set_range(blob_T *dest, int n1, int n2, typval_T *src) { if (n2 - n1 + 1 != tv_blob_len(src->vval.v_blob)) { emsg(_("E972: Blob value does not have the right number of bytes")); return FAIL; } - for (int il = (int)n1, ir = 0; il <= (int)n2; il++) { + for (int il = n1, ir = 0; il <= n2; il++) { tv_blob_set(dest, il, tv_blob_get(src->vval.v_blob, ir++)); } return OK; diff --git a/src/nvim/testdir/test_blob.vim b/src/nvim/testdir/test_blob.vim index 310582240c..2c145f2019 100644 --- a/src/nvim/testdir/test_blob.vim +++ b/src/nvim/testdir/test_blob.vim @@ -715,6 +715,18 @@ func Test_blob2string() call assert_equal(v, string(b)) endfunc +func Test_blob_repeat() + call assert_equal(0z, repeat(0z00, 0)) + call assert_equal(0z00, repeat(0z00, 1)) + call assert_equal(0z0000, repeat(0z00, 2)) + call assert_equal(0z00000000, repeat(0z0000, 2)) + + call assert_equal(0z, repeat(0z12, 0)) + call assert_equal(0z, repeat(0z1234, 0)) + call assert_equal(0z1234, repeat(0z1234, 1)) + call assert_equal(0z12341234, repeat(0z1234, 2)) +endfunc + " Test for blob allocation failure func Test_blob_alloc_failure() CheckFunction test_alloc_fail |