changeset 11:7360d752183e

Added lists.h: Manage linked lists using token concatenation to generate functions for a specified type of structure. At the moment only single linked list is supported.
author David Demelier <markand@malikania.fr>
date Wed, 07 Sep 2011 21:12:48 +0200
parents da47652b60c5
children cbfe95c9f7b7
files lists.h
diffstat 1 files changed, 118 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lists.h	Wed Sep 07 21:12:48 2011 +0200
@@ -0,0 +1,118 @@
+/*
+ * lists.h -- function to manipulate linked lists
+ *
+ * Copyright (c) 2011, David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LISTS_H_
+#define _LISTS_H_
+
+/*
+ * Available function for single linked lists :
+ *
+ * <prefix> refers to the prefix argument given to the LIST_IMPLEMENTS macro.
+ * all function will use this prefix to determine the correct function.
+ *
+ * <type> refers to the data type used as template.
+ *
+ * o void slist_<prefix>_init(struct slist *sls);
+ *	Initialize the `ls' list structure.
+ *
+ * o void slist_<prefix>_push(struct slist *sls, <type> *var)
+ *	Add the `var' to the beginning of the list, if the list is empty
+ *	the tail also refers to the head.
+ *
+ * o void slist_<prefix>_pop(struct slist *sls)
+ *	Remove the first element from the list.
+ *
+ * o void slist_<prefix>_after(struct slist *sls, <type> *after, <type> *var)
+ *	Insert after the object referenced by `after'.
+ *
+ * o void slist_<prefix>_remove(struct slist *sls, <type> *var)
+ *	Remove the var element from the list.
+ *
+ * o <type> *slist_<prefix>_head(const struct slist *sls)
+ *	Returns the first list element.
+ */
+
+struct slist {
+	int	length;
+	void	*head;
+};
+
+/*
+ * This declare prototype function, to prevent reimplementing function
+ * that already exists somewhere.
+ */
+
+#define SLIST_HEADER(attr, prefix, type)					\
+attr void slist_##prefix##_init(struct slist *);				\
+attr void slist_##prefix##_push(struct slist *, type *);			\
+attr void slist_##prefix##_pop(struct slist *);					\
+attr void slist_##prefix##_after(struct slist *, type *, type *);		\
+attr void slist_##prefix##_remove(struct slist *, type *);			\
+attr type *slist_##prefix##_head(const struct slist *);
+
+/*
+ * Generate available function with the specified prefix. Name argument
+ * is the next pointer entry in the `type' structure used to go through
+ * the list.
+ */
+
+#define SLIST_IMPLEMENTS(attr, prefix, type, field)				\
+attr void									\
+slist_##prefix##_init(struct slist *sls)					\
+{										\
+	sls->length	= 0;							\
+	sls->head	= NULL;							\
+}										\
+										\
+attr void									\
+slist_##prefix##_push(struct slist *sls, type *var)				\
+{										\
+	var->field = sls->head;							\
+	sls->head = var;							\
+	sls->length++;								\
+}										\
+										\
+attr void									\
+slist_##prefix##_pop(struct slist *sls)						\
+{										\
+	if (sls->head) {							\
+		sls->head = ((type *)sls->head)->field;				\
+		sls->length--;							\
+	}									\
+}										\
+										\
+attr void									\
+slist_##prefix##_after(struct slist *sls, type *after, type *var)		\
+{										\
+	var->field = after->field;						\
+	after->field = var;							\
+	sls->length++;								\
+}										\
+										\
+attr type *									\
+slist_##prefix##_head(const struct slist *sls)					\
+{										\
+	return (type *) sls->head;						\
+}
+
+#define SLIST_FOREACH(list, entry, field)					\
+	for (entry = (list)->head;						\
+	    entry;								\
+	    entry = entry->field)
+
+#endif /* _LISTS_H_ */