diff src/blob.c @ 17530:ef23ec1eee54 v8.1.1763

patch 8.1.1763: evalfunc.c is still too big commit https://github.com/vim/vim/commit/9f9fe37f6750f342255a51f158a7bb372c827f7f Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jul 27 23:12:12 2019 +0200 patch 8.1.1763: evalfunc.c is still too big Problem: Evalfunc.c is still too big. Solution: Move dict and list functions to a better place.
author Bram Moolenaar <Bram@vim.org>
date Sat, 27 Jul 2019 23:15:05 +0200
parents a0eb2ff0f297
children c469e1930456
line wrap: on
line diff
--- 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) */