diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-07-27 23:12:12 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-07-27 23:12:12 +0200 |
commit | 9f9fe37f6750f342255a51f158a7bb372c827f7f (patch) | |
tree | c140c42b9f184c0bba789f3d4ed749a1e6fb3ed4 /src/blob.c | |
parent | c273405188cc2f19e949089cda1f92bd81610dac (diff) | |
download | vim-git-9f9fe37f6750f342255a51f158a7bb372c827f7f.tar.gz |
patch 8.1.1763: evalfunc.c is still too bigv8.1.1763
Problem: Evalfunc.c is still too big.
Solution: Move dict and list functions to a better place.
Diffstat (limited to 'src/blob.c')
-rw-r--r-- | src/blob.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/blob.c b/src/blob.c index fb40a5779..278ced62c 100644 --- a/src/blob.c +++ b/src/blob.c @@ -258,4 +258,74 @@ failed: return NULL; } +/* + * "remove({blob})" function + */ + void +blob_remove(typval_T *argvars, typval_T *rettv) +{ + int error = FALSE; + long idx = (long)tv_get_number_chk(&argvars[1], &error); + long end; + + if (!error) + { + blob_T *b = argvars[0].vval.v_blob; + int len = blob_len(b); + char_u *p; + + if (idx < 0) + // count from the end + idx = len + idx; + if (idx < 0 || idx >= len) + { + semsg(_(e_blobidx), idx); + return; + } + if (argvars[2].v_type == VAR_UNKNOWN) + { + // Remove one item, return its value. + p = (char_u *)b->bv_ga.ga_data; + rettv->vval.v_number = (varnumber_T) *(p + idx); + mch_memmove(p + idx, p + idx + 1, (size_t)len - idx - 1); + --b->bv_ga.ga_len; + } + else + { + blob_T *blob; + + // Remove range of items, return list with values. + end = (long)tv_get_number_chk(&argvars[2], &error); + if (error) + return; + if (end < 0) + // count from the end + end = len + end; + if (end >= len || idx > end) + { + semsg(_(e_blobidx), end); + return; + } + blob = blob_alloc(); + if (blob == NULL) + return; + blob->bv_ga.ga_len = end - idx + 1; + if (ga_grow(&blob->bv_ga, end - idx + 1) == FAIL) + { + vim_free(blob); + return; + } + p = (char_u *)b->bv_ga.ga_data; + mch_memmove((char_u *)blob->bv_ga.ga_data, p + idx, + (size_t)(end - idx + 1)); + ++blob->bv_refcount; + rettv->v_type = VAR_BLOB; + rettv->vval.v_blob = blob; + + mch_memmove(p + idx, p + end + 1, (size_t)(len - end)); + b->bv_ga.ga_len -= end - idx + 1; + } + } +} + #endif /* defined(FEAT_EVAL) */ |