changeset 91:b3ba5f5df3b9

New style for array.c and array.h, no pointer to these object thus no need to check if array_new succeeded. array_set() added to use own allocation functions and other settings at any time
author David Demelier <markand@malikania.fr>
date Tue, 03 Jan 2012 16:05:06 +0100
parents 145493469aa0
children 4d723e81b685
files array.c array.h
diffstat 2 files changed, 59 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/array.c	Wed Nov 30 11:11:51 2011 +0100
+++ b/array.c	Tue Jan 03 16:05:06 2012 +0100
@@ -26,26 +26,57 @@
 
 static int	array_grow(struct array *);
 
-struct array *
-array_new(enum array_type type, size_t unit, int length)
+int
+array_new(struct array *arr, size_t unit)
 {
-	struct array *arr;
+	if (unit == 0)
+		return -1;
 
-	if (unit == 0 || (arr = malloc(sizeof (struct array))) == NULL)
-		return NULL;
-
-	memset(arr, 0, sizeof (struct array));
-	arr->type	= type;
-	arr->bsize	= (length == 0) ? ARRAY_DEFAULT_BSIZE : length;
 	arr->unit	= unit;
 	arr->size	= OFFSET(arr->bsize);
 
-	if ((arr->data = malloc(arr->size)) == NULL) {
-		free(arr);
-		return NULL;
-	}
+	/* Set default if needed */
+	arr->bsize	= (arr->bsize == 0) ? ARRAY_DEFAULT_BSIZE : arr->bsize;
+	arr->malloc	= (arr->malloc == NULL) ? &malloc : arr->malloc;
+	arr->realloc	= (arr->realloc == NULL) ? &realloc : arr->realloc;
+
+	if ((arr->data = arr->malloc(arr->size)) == NULL)
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Valid options that can be set for an array :
+ * l -> optional array block size of type int
+ * m -> malloc function that must matches void * (*malloc)(size_t)
+ * r -> realloc function that must matches void * (*realloc)(void *, size_t)
+ * t -> type of array of type enum array_type
+ */
 
-	return arr;
+void
+array_set(struct array *arr, const char *fmt, ...)
+{
+	va_list ap;
+	const char *p;
+
+	va_start(ap, fmt);
+	for (p = fmt; *p != '\0'; ++p)
+		switch (*p) {
+		case 'l':
+			arr->bsize = va_arg(ap, int);
+			break;
+		case 'm':
+			arr->malloc = va_arg(ap, void * (*)(size_t));
+			break;
+		case 'r':
+			arr->realloc = va_arg(ap, void *(*)(void *, size_t));
+			break;
+		case 't':
+			arr->type = va_arg(ap, enum array_type);
+		default:
+			break;
+		}
 }
 
 /*
@@ -178,7 +209,7 @@
 	 * function.
 	 */
 
-	if ((tmp = malloc(arr->unit)) == NULL)
+	if ((tmp = arr->malloc(arr->unit)) == NULL)
 		return -1;
 
 	memcpy((char *)tmp, (char *)arr->data + OFFSET(i1), arr->unit);
@@ -282,8 +313,6 @@
 
 	if (arr->data)
 		free(arr->data);
-
-	free(arr);
 }
 
 /*
@@ -299,7 +328,7 @@
 		return 0;
 
 	if (arr->type == ARRAY_AUTO) {
-		if ((arr->data = realloc(arr->data, arr->size +
+		if ((arr->data = arr->realloc(arr->data, arr->size +
 		    OFFSET(arr->bsize))) == NULL)
 			return -1;
 
--- a/array.h	Wed Nov 30 11:11:51 2011 +0100
+++ b/array.h	Tue Jan 03 16:05:06 2012 +0100
@@ -23,11 +23,15 @@
 extern "C" {
 #endif
 
+#include <stdarg.h>
+
+#ifndef ARRAY_DEFAULT_BSIZE
 #define ARRAY_DEFAULT_BSIZE	128
+#endif
 
 enum array_type {
-	ARRAY_FIXED	= 0,
-	ARRAY_AUTO	= 1
+	ARRAY_AUTO	= 0,
+	ARRAY_FIXED	= 1
 };
 
 struct array {
@@ -38,12 +42,17 @@
 	size_t		unit;	/* unit size (sizeof the object) */
 	int		bsize;	/* block size (used when growing array) */
 	int		i;	/* only for ARRAY_FOREACH(_R) */
+
+	/* Own alloc function */
+	void * (*malloc)(size_t);
+	void * (*realloc)(void *, size_t);
 };
 
 typedef void (*array_map_fn)(void *, void *);
 typedef int (*array_cmp_fn)(void *, void *);
 
-struct array	*array_new(enum array_type, size_t, int);
+int		array_new(struct array *, size_t);
+void		array_set(struct array *arr, const char *fmt, ...);
 int		array_push(struct array *, const void *);
 int		array_insert(struct array *, const void *, int);
 int		array_append(struct array *, const void *);
@@ -66,10 +75,6 @@
 	((type *)(a)->data)[((i) < 0)						\
 	    ? 0 : ((i) >= (a)->length) ? (a)->length - 1 : (i)]
 
-#define ARRAY_FOREACH_R(a, var)							\
-	for ((a)->i = 0, var = ARRAY_TAIL((a));					\
-	    (a)->i < (a)->length; ++(a)->i, --var)
-
 #define ARRAY_FOREACH(a, var, type)						\
 	for ((a)->i = 0, var = ARRAY_HEAD((a), type);				\
 		(a)->i < (a)->length;						\