diff options
author | Bakudankun <bakudankun@gmail.com> | 2022-09-09 18:46:47 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-09-09 18:46:47 +0100 |
commit | 375141e1f80dced9be738568a3418f65813f4a2f (patch) | |
tree | be23086bf0c21bbf564b42298909d856ac6780cf /src/evalfunc.c | |
parent | 0adae2da17598669e442ba38547ab18a6c1406de (diff) |
patch 9.0.0430: cannot use repeat() with a blobv9.0.0430
Problem: Cannot use repeat() with a blob.
Solution: Implement blob repeat. (closes #11090)
Diffstat (limited to 'src/evalfunc.c')
-rw-r--r-- | src/evalfunc.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c index 2c041fa6de..bc0e23e9c8 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -872,6 +872,7 @@ arg_repeat1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) || type->tt_type == VAR_UNKNOWN || type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER + || type->tt_type == VAR_BLOB || type->tt_type == VAR_LIST) return OK; @@ -4400,6 +4401,10 @@ f_foreground(typval_T *argvars UNUSED, typval_T *rettv UNUSED) #endif } +/* + * "function()" function + * "funcref()" function + */ static void common_function(typval_T *argvars, typval_T *rettv, int is_funcref) { @@ -8399,18 +8404,19 @@ f_rename(typval_T *argvars, typval_T *rettv) f_repeat(typval_T *argvars, typval_T *rettv) { char_u *p; - int n; + varnumber_T n; int slen; int len; char_u *r; int i; if (in_vim9script() - && (check_for_string_or_number_or_list_arg(argvars, 0) == FAIL + && (check_for_string_or_number_or_list_or_blob_arg(argvars, 0) + == FAIL || check_for_number_arg(argvars, 1) == FAIL)) return; - n = (int)tv_get_number(&argvars[1]); + n = tv_get_number(&argvars[1]); if (argvars[0].v_type == VAR_LIST) { if (rettv_list_alloc(rettv) == OK && argvars[0].vval.v_list != NULL) @@ -8419,6 +8425,35 @@ f_repeat(typval_T *argvars, typval_T *rettv) argvars[0].vval.v_list, NULL) == FAIL) break; } + else if (argvars[0].v_type == VAR_BLOB) + { + if (rettv_blob_alloc(rettv) == FAIL + || argvars[0].vval.v_blob == NULL + || n <= 0) + return; + + slen = argvars[0].vval.v_blob->bv_ga.ga_len; + len = (int)slen * n; + if (len <= 0) + return; + + if (ga_grow(&rettv->vval.v_blob->bv_ga, len) == FAIL) + return; + + rettv->vval.v_blob->bv_ga.ga_len = len; + + for (i = 0; i < slen; ++i) + if (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) + blob_set_range(rettv->vval.v_blob, + (long)i * slen, ((long)i + 1) * slen - 1, argvars); + } else { p = tv_get_string(&argvars[0]); |