changeset 269:9b758eb84556

core: add alloc_rearray0 function
author David Demelier <markand@malikania.fr>
date Fri, 11 Dec 2020 11:33:58 +0100
parents 3f710c68bb97
children 2d8d1cacda36
files doc/docs/dev/api/core/alloc.md libmlk-core/core/alloc.c libmlk-core/core/alloc.h tests/test-alloc.c
diffstat 4 files changed, 115 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/doc/docs/dev/api/core/alloc.md	Fri Dec 11 11:04:36 2020 +0100
+++ b/doc/docs/dev/api/core/alloc.md	Fri Dec 11 11:33:58 2020 +0100
@@ -185,12 +185,12 @@
 
 ### alloc\_array
 
-Allocate an uninitialized array of `n` elements of `size` individually. Returns
-the result of the current [alloc](#alloc) function set.
+Allocate an uninitialized array of `len` elements of `elemsize` individually.
+Returns the result of the current [alloc](#alloc) function set.
 
 ```c
 void *
-alloc_array(size_t n, size_t size)
+alloc_array(size_t len, size_t elemsize)
 ```
 
 ### alloc\_array0
@@ -199,27 +199,40 @@
 
 ```c
 void *
-alloc_array0(size_t n, size_t size)
+alloc_array0(size_t len, size_t elemsize)
 ```
 
 ### alloc\_renew
 
-Reallocate the pointer `ptr` (which may be NULL) to the new `amount` size. The
+Reallocate the pointer `ptr` (which may be NULL) to the new `size` size. The
 size can be 0. Returns the result of the current [alloc](#alloc) function set.
 
 ```c
 void *
-alloc_renew(void *ptr, size_t amount)
+alloc_renew(void *ptr, size_t size)
 ```
 
 ### alloc\_rearray
 
-Reallocate the `ptr` (which may be NULL) as an array of `n` elements of `size`
-individually. Returns the result of the current [alloc](#alloc) function set.
+Reallocate the pointer `ptr` (which may be NULL) as an array of `newlen`
+elements of `elemsize` individually. Returns the result of the current
+[realloc](#realloc) function set.
 
 ```c
 void *
-alloc_rearray(void *ptr, size_t n, size_t size)
+alloc_rearray(void *ptr, size_t newlen, size_t elemsize)
+```
+
+### alloc\_rearray0
+
+Reallocate the `ptr` (which maybe NULL) with the `oldlen` as current number of
+elements of `elemsize` to the `newlen`. If the `newlen` is greater than oldlen,
+the new region is cleared with 0. Returns the result of the current
+[realloc](#realloc) function set.
+
+```c
+void *
+alloc_rearray0(void *ptr, size_t oldlen, size_t newlen, size_t elemsize)
 ```
 
 ### alloc\_dup
@@ -231,6 +244,16 @@
 alloc_dup(const void *ptr, size_t size)
 ```
 
+### alloc\_sdup
+
+Duplicate the string `src`. Returns the result of current [alloc](#alloc)
+function set.
+
+```c
+char *
+alloc_sdup(const char *src)
+```
+
 ### alloc\_pool\_init
 
 Initialize the `pool` as an array where elements have `elemsize` size. Optional
--- a/libmlk-core/core/alloc.c	Fri Dec 11 11:04:36 2020 +0100
+++ b/libmlk-core/core/alloc.c	Fri Dec 11 11:33:58 2020 +0100
@@ -93,52 +93,68 @@
 }
 
 void *
-alloc_array(size_t n, size_t size)
+alloc_array(size_t len, size_t elemsize)
 {
-	assert(n != 0);
-	assert(size != 0);
+	assert(len != 0);
+	assert(elemsize != 0);
 
-	size_t total = n * size;
+	size_t size = len * elemsize;
 
-	if (total / n != size)
+	if (size / len != elemsize)
 		return errorf("%s", strerror(ENOMEM)), NULL;
 
-	return funcs->alloc(total);
+	return funcs->alloc(size);
 }
 
 void *
-alloc_array0(size_t n, size_t size)
+alloc_array0(size_t len, size_t elemsize)
 {
-	assert(n != 0);
-	assert(size != 0);
+	assert(len != 0);
+	assert(elemsize != 0);
 
 	void *mem;
-	size_t total = n * size;
+	size_t size = len * elemsize;
 
-	if (total / n != size)
+	if (size / len != elemsize)
 		return errorf("%s", strerror(ENOMEM)), NULL;
 
-	if ((mem = funcs->alloc(total)))
-		memset(mem, 0, total);
+	if ((mem = funcs->alloc(size)))
+		memset(mem, 0, size);
 
 	return mem;
 }
 
 void *
-alloc_renew(void *ptr, size_t amount)
+alloc_renew(void *ptr, size_t size)
 {
-	return funcs->realloc(ptr, amount);
+	return funcs->realloc(ptr, size);
 }
 
 void *
-alloc_rearray(void *ptr, size_t n, size_t size)
+alloc_rearray(void *ptr, size_t len, size_t elemsize)
 {
-	size_t total = n * size;
+	size_t size = len * elemsize;
 
-	if (total / n != size)
+	if (size / len != elemsize)
 		return errorf("%s", strerror(ENOMEM)), NULL;
 
-	return funcs->realloc(ptr, total);
+	return funcs->realloc(ptr, size);
+}
+
+void *
+alloc_rearray0(void *ptr, size_t oldlen, size_t newlen, size_t elemsize)
+{
+	size_t size = newlen * elemsize;
+
+	if (size / newlen != elemsize)
+		return errorf("%s", strerror(ENOMEM)), NULL;
+	if (!(ptr = funcs->realloc(ptr, size)))
+		return false;
+
+	if (newlen > oldlen)
+		memset((unsigned char *)ptr + (oldlen * elemsize), 0, (newlen - oldlen) * elemsize);
+
+	return ptr;
 }
 
 void *
--- a/libmlk-core/core/alloc.h	Fri Dec 11 11:04:36 2020 +0100
+++ b/libmlk-core/core/alloc.h	Fri Dec 11 11:33:58 2020 +0100
@@ -54,20 +54,26 @@
 alloc_new0(size_t size);
 
 void *
-alloc_array(size_t n, size_t size);
+alloc_array(size_t len, size_t elemsize);
+
+void *
+alloc_array0(size_t len, size_t elemsize);
 
 void *
-alloc_array0(size_t n, size_t size);
+alloc_renew(void *ptr, size_t size);
 
 void *
-alloc_renew(void *ptr, size_t amount);
+alloc_rearray(void *ptr, size_t newlen, size_t elemsize);
 
 void *
-alloc_rearray(void *ptr, size_t n, size_t size);
+alloc_rearray0(void *ptr, size_t oldlen, size_t newlen, size_t elemsize);
 
 void *
 alloc_dup(const void *ptr, size_t size);
 
+char *
+alloc_sdup(const char *src);
+
 /* alloc_pool functions. */
 bool
 alloc_pool_init(struct alloc_pool *pool, size_t elemsize, void (*finalizer)(void *));
--- a/tests/test-alloc.c	Fri Dec 11 11:04:36 2020 +0100
+++ b/tests/test-alloc.c	Fri Dec 11 11:33:58 2020 +0100
@@ -27,7 +27,41 @@
 };
 
 GREATEST_TEST
-test_basics_simple(void)
+test_array_simple(void)
+{
+	struct point *points;
+
+	GREATEST_ASSERT((points = alloc_array0(2, sizeof (*points))));
+	GREATEST_ASSERT_EQ(0, points[0].x);
+	GREATEST_ASSERT_EQ(0, points[0].y);
+	GREATEST_ASSERT_EQ(0, points[1].x);
+	GREATEST_ASSERT_EQ(0, points[1].y);
+
+	points[0].x = 10;
+	points[0].y = 20;
+	points[1].x = 30;
+	points[1].y = 40;
+
+	GREATEST_ASSERT((points = alloc_rearray0(points, 2, 4, sizeof (*points))));
+	GREATEST_ASSERT_EQ(10, points[0].x);
+	GREATEST_ASSERT_EQ(20, points[0].y);
+	GREATEST_ASSERT_EQ(30, points[1].x);
+	GREATEST_ASSERT_EQ(40, points[1].y);
+	GREATEST_ASSERT_EQ(0,  points[2].x);
+	GREATEST_ASSERT_EQ(0,  points[2].y);
+	GREATEST_ASSERT_EQ(0,  points[3].x);
+	GREATEST_ASSERT_EQ(0,  points[3].y);
+
+	GREATEST_PASS();
+}
+
+GREATEST_SUITE(suite_basics)
+{
+	GREATEST_RUN_TEST(test_array_simple);
+}
+
+GREATEST_TEST
+test_pool_simple(void)
 {
 	struct alloc_pool pool;
 	struct point *p;
@@ -71,9 +105,9 @@
 	GREATEST_PASS();
 }
 
-GREATEST_SUITE(suite_basics)
+GREATEST_SUITE(suite_pool)
 {
-	GREATEST_RUN_TEST(test_basics_simple);
+	GREATEST_RUN_TEST(test_pool_simple);
 }
 
 GREATEST_MAIN_DEFS();
@@ -83,6 +117,7 @@
 {
 	GREATEST_MAIN_BEGIN();
 	GREATEST_RUN_SUITE(suite_basics);
+	GREATEST_RUN_SUITE(suite_pool);
 	GREATEST_MAIN_END();
 
 	return 0;