view lists.h @ 14:2d112b8a3756

Fix typo
author David Demelier <markand@malikania.fr>
date Wed, 07 Sep 2011 23:32:10 +0200
parents 7360d752183e
children
line wrap: on
line source

/*
 * 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_ */