changeset 92:4d723e81b685

Same thing for parray
author David Demelier <markand@malikania.fr>
date Tue, 03 Jan 2012 17:54:35 +0100
parents b3ba5f5df3b9
children 9ebea85c7765
files array.c array.h parray.c parray.h
diffstat 4 files changed, 89 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/array.c	Tue Jan 03 16:05:06 2012 +0100
+++ b/array.c	Tue Jan 03 17:54:35 2012 +0100
@@ -35,8 +35,8 @@
 	arr->unit	= unit;
 	arr->size	= OFFSET(arr->bsize);
 
-	/* Set default if needed */
-	arr->bsize	= (arr->bsize == 0) ? ARRAY_DEFAULT_BSIZE : arr->bsize;
+	/* Set defaults 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;
 
--- a/array.h	Tue Jan 03 16:05:06 2012 +0100
+++ b/array.h	Tue Jan 03 17:54:35 2012 +0100
@@ -41,9 +41,9 @@
 	size_t		size;	/* current buffer size (allocated memory) */
 	size_t		unit;	/* unit size (sizeof the object) */
 	int		bsize;	/* block size (used when growing array) */
-	int		i;	/* only for ARRAY_FOREACH(_R) */
+	int		i;	/* only for ARRAY_FOREACH */
 
-	/* Own alloc function */
+	/* Own allocation functions */
 	void * (*malloc)(size_t);
 	void * (*realloc)(void *, size_t);
 };
@@ -51,21 +51,21 @@
 typedef void (*array_map_fn)(void *, void *);
 typedef int (*array_cmp_fn)(void *, void *);
 
-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 *);
-void		array_pop(struct array *);
-void		array_unqueue(struct array *);
-void		array_remove(struct array *, int);
-void		array_unref(struct array *, const void *);
-int		array_iswap(struct array *, int, int);
-int		array_pswap(struct array *, const void *, const void *);
-void		array_map(const struct array *, array_map_fn, void *);
-int		array_find(const struct array *, array_cmp_fn, void *, void *);
-void		array_clear(struct array *);
-void		array_free(struct array *);
+int	array_new(struct array *, size_t);
+void	array_set(struct array *, const char *, ...);
+int	array_push(struct array *, const void *);
+int	array_insert(struct array *, const void *, int);
+int	array_append(struct array *, const void *);
+void	array_pop(struct array *);
+void	array_unqueue(struct array *);
+void	array_remove(struct array *, int);
+void	array_unref(struct array *, const void *);
+int	array_iswap(struct array *, int, int);
+int	array_pswap(struct array *, const void *, const void *);
+void	array_map(const struct array *, array_map_fn, void *);
+int	array_find(const struct array *, array_cmp_fn, void *, void *);
+void	array_clear(struct array *);
+void	array_free(struct array *);
 
 #define ARRAY_HEAD(a, type)							\
 	(((type *)a->data)[0])
--- a/parray.c	Tue Jan 03 16:05:06 2012 +0100
+++ b/parray.c	Tue Jan 03 17:54:35 2012 +0100
@@ -26,26 +26,55 @@
 
 static int	parray_grow(struct parray *);
 
-struct parray *
-parray_new(enum parray_type type, int length)
+int
+parray_new(struct parray *arr)
 {
-	struct parray *arr;
+	/* Set defaults if needed */
+	arr->bsize	= (arr->bsize <= 0) ? PARRAY_DEFAULT_BSIZE : arr->bsize;
+	arr->malloc	= (arr->malloc == NULL) ? &malloc : arr->malloc;
+	arr->realloc	= (arr->realloc == NULL) ? &realloc : arr->realloc;
 
-	if ((arr = malloc(sizeof (struct parray))) == NULL)
-		return NULL;
-
-	memset(arr, 0, sizeof (struct parray));
-
-	arr->type	= type;
-	arr->bsize	= (length == 0) ? PARRAY_DEFAULT_BSIZE : length;
 	arr->size	= LENGTH(arr->bsize);
 
-	if ((arr->datas = calloc(arr->bsize, sizeof (void *))) == NULL) {
-		free(arr);
-		return NULL;
-	}
+	if ((arr->datas = arr->malloc(arr->size)) == NULL)
+		return -1;
+
+	memset(arr->datas, 0, arr->bsize);
+
+	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
+parray_set(struct parray *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 parray_type);
+		default:
+			break;
+		}
 }
 
 /*
@@ -263,8 +292,6 @@
 
 	if (arr->datas)
 		free(arr->datas);
-
-	free(arr);
 }
 
 /*
@@ -280,7 +307,7 @@
 		return 0;
 
 	if (arr->type == PARRAY_AUTO) {
-		if ((arr->datas = realloc(arr->datas, arr->size +
+		if ((arr->datas = arr->realloc(arr->datas, arr->size +
 		    LENGTH(arr->bsize))) == NULL)
 			return -1;
 
--- a/parray.h	Tue Jan 03 16:05:06 2012 +0100
+++ b/parray.h	Tue Jan 03 17:54:35 2012 +0100
@@ -23,11 +23,15 @@
 extern "C" {
 #endif
 
+#include <stdarg.h>
+
+#ifndef PARRAY_DEFAULT_BSIZE
 #define PARRAY_DEFAULT_BSIZE	128
+#endif
 
 enum parray_type {
-	PARRAY_FIXED	= 0,
-	PARRAY_AUTO	= 1
+	PARRAY_AUTO	= 0,
+	PARRAY_FIXED	= 1
 };
 
 struct parray {
@@ -37,25 +41,30 @@
 	size_t		size;		/* current buffer size (allocated memory) */
 	int		bsize;		/* block size (used when growing array) */
 	int		i;		/* only for PARRAY_FOREACH(_R) */
+
+	/* Own allocation functions */
+	void * (*malloc)(size_t);
+	void * (*realloc)(void *, size_t);
 };
 
 typedef void (*parray_map_fn)(void *, void *);
 typedef int (*parray_cmp_fn)(void *, void *);
 
-struct parray	*parray_new(enum parray_type, int);
-int		parray_push(struct parray *, void *);
-int		parray_insert(struct parray *, void *, int);
-int		parray_append(struct parray *, void *);
-void		parray_pop(struct parray *);
-void		parray_unqueue(struct parray *);
-void		parray_remove(struct parray *, int);
-void		parray_unref(struct parray *, const void *);
-int		parray_iswap(struct parray *, int, int);
-int		parray_pswap(struct parray *, const void *, const void *);
-void		parray_map(const struct parray *, parray_map_fn, void *);
-int		parray_find(const struct parray *, parray_cmp_fn, void **, void *);
-void		parray_clear(struct parray *);
-void		parray_free(struct parray *);
+int	parray_new(struct parray *);
+void	parray_set(struct parray *, const char *, ...);
+int	parray_push(struct parray *, void *);
+int	parray_insert(struct parray *, void *, int);
+int	parray_append(struct parray *, void *);
+void	parray_pop(struct parray *);
+void	parray_unqueue(struct parray *);
+void	parray_remove(struct parray *, int);
+void	parray_unref(struct parray *, const void *);
+int	parray_iswap(struct parray *, int, int);
+int	parray_pswap(struct parray *, const void *, const void *);
+void	parray_map(const struct parray *, parray_map_fn, void *);
+int	parray_find(const struct parray *, parray_cmp_fn, void **, void *);
+void	parray_clear(struct parray *);
+void	parray_free(struct parray *);
 
 #define PARRAY_HEAD(a)								\
 	(a->datas[0])