summaryrefslogtreecommitdiff
path: root/src/blob.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-07-27 23:12:12 +0200
committerBram Moolenaar <Bram@vim.org>2019-07-27 23:12:12 +0200
commit9f9fe37f6750f342255a51f158a7bb372c827f7f (patch)
treec140c42b9f184c0bba789f3d4ed749a1e6fb3ed4 /src/blob.c
parentc273405188cc2f19e949089cda1f92bd81610dac (diff)
downloadvim-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.c70
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) */