diff src/userfunc.c @ 31653:ec76f9d2319e v9.0.1159

patch 9.0.1159: extends argument for class not implemented yet Commit: https://github.com/vim/vim/commit/8367716a6e9589d61a771e6c329da05c9b55e61a Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jan 8 19:54:10 2023 +0000 patch 9.0.1159: extends argument for class not implemented yet Problem: Extends argument for class not implemented yet. Solution: Basic implementation of "extends".
author Bram Moolenaar <Bram@vim.org>
date Sun, 08 Jan 2023 21:00:05 +0100
parents 5c1b7a87466e
children 01d05b001dda
line wrap: on
line diff
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -5516,6 +5516,74 @@ get_user_func_name(expand_T *xp, int idx
 }
 
 /*
+ * Make a copy of a function.
+ * Intended to be used for a function defined on a base class that has a copy
+ * on the child class.
+ * The copy has uf_refcount set to one.
+ * Returns NULL when out of memory.
+ */
+    ufunc_T *
+copy_function(ufunc_T *fp)
+{
+    // The struct may have padding, make sure we allocate at least the size of
+    // the struct.
+    size_t len = offsetof(ufunc_T, uf_name) + STRLEN(fp->uf_name) + 1;
+    ufunc_T *ufunc = alloc_clear(len < sizeof(ufunc_T) ? sizeof(ufunc_T) : len);
+    if (ufunc == NULL)
+	return NULL;
+
+    // Most things can just be copied.
+    *ufunc = *fp;
+
+    ufunc->uf_def_status = UF_TO_BE_COMPILED;
+    ufunc->uf_dfunc_idx = 0;
+    ufunc->uf_class = NULL;
+
+    ga_copy_strings(&fp->uf_args, &ufunc->uf_args);
+    ga_copy_strings(&fp->uf_def_args, &ufunc->uf_def_args);
+
+    if (ufunc->uf_arg_types != NULL)
+    {
+	// "uf_arg_types" is an allocated array, make a copy.
+	type_T **at = ALLOC_CLEAR_MULT(type_T *, ufunc->uf_args.ga_len);
+	if (at != NULL)
+	{
+	    mch_memmove(at, ufunc->uf_arg_types,
+				     sizeof(type_T *) * ufunc->uf_args.ga_len);
+	    ufunc->uf_arg_types = at;
+	}
+    }
+
+    // TODO: how about the types themselves? they can be freed when the
+    // original function is freed:
+    //    type_T	**uf_arg_types;
+    //    type_T	*uf_ret_type;
+
+    ufunc->uf_type_list.ga_len = 0;
+    ufunc->uf_type_list.ga_data = NULL;
+
+    // TODO:   partial_T	*uf_partial;
+
+    if (ufunc->uf_va_name != NULL)
+	ufunc->uf_va_name = vim_strsave(ufunc->uf_va_name);
+
+    // TODO:
+    //    type_T	*uf_va_type;
+    //    type_T	*uf_func_type;
+
+    ufunc->uf_block_depth = 0;
+    ufunc->uf_block_ids = NULL;
+
+    ga_copy_strings(&fp->uf_lines, &ufunc->uf_lines);
+
+    ufunc->uf_refcount = 1;
+    ufunc->uf_name_exp = NULL;
+    STRCPY(ufunc->uf_name, fp->uf_name);
+
+    return ufunc;
+}
+
+/*
  * ":delfunction {name}"
  */
     void