# HG changeset patch # User Tero Marttila # Date 1236874067 -7200 # Node ID 3715247e8f5aabfe239dcd686fe4cd667bce3fe9 # Parent 763f65f9df0ccc855dbbb07b6f75305a80cc92c0 add a kind of semi-generic chain-list implementation diff -r 763f65f9df0c -r 3715247e8f5a src/chain.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/chain.c Thu Mar 12 18:07:47 2009 +0200 @@ -0,0 +1,39 @@ +#include "chain.h" + +#include + +err_t chain_add (struct chain_list *list, const void *chain, void *arg) +{ + struct chain_head *item; + + // allocate the chain item + if ((item = calloc(1, sizeof(*item))) == NULL) + return ERR_CALLOC; + + // store + item->chain = chain; + item->arg = arg; + + // append + STAILQ_INSERT_TAIL(list, item, node); + + // ok + return SUCCESS; +} + +void chain_free (struct chain_list *list) +{ + // start from the first item + struct chain_head *next = STAILQ_FIRST(list); + + // clean up any handler chains + while (next) { + struct chain_head *node = next; + + // update next + next = STAILQ_NEXT(node, node); + + // free + free(node); + } +} diff -r 763f65f9df0c -r 3715247e8f5a src/chain.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/chain.h Thu Mar 12 18:07:47 2009 +0200 @@ -0,0 +1,61 @@ +#ifndef CHAIN_H +#define CHAIN_H + +/** + * Defines a generalized "chain of things" behaviour. + * + * The structure of this is a CHAIN_LIST, which contains a number of CHAIN_HEAD items, which then contain a number of + * induvidual items. + */ +#include "error.h" +#include + +/** + * The chain header. + */ +struct chain_head { + const void *chain; + + void *arg; + + STAILQ_ENTRY(chain_head) node; +}; + +/** + * @struct chain_list + * + * The chain list + */ +STAILQ_HEAD(chain_list, chain_head); + +/** + * Initialize a `struct chain_list` + */ +#define CHAIN_INIT(list_ptr) STAILQ_INIT(list_ptr) + +/** + * Add an item onto the end of a chain_list + */ +err_t chain_add (struct chain_list *list, const void *chain, void *arg); + +/** + * Iterate over the contents of a chain_list + * + * struct chain_list *list = ...; + * struct chain_head *head; + * struct foo *foo; + * + * CHAIN_FOREACH(list, head) { + * for (foo = head->chain; foo->bar; foo++) { + * foo->bar(foo, head->arg); + * } + * } + */ +#define CHAIN_FOREACH(list_ptr, head_ptr) STAILQ_FOREACH(head_ptr, list_ptr, node) + +/** + * Free a chain_list + */ +void chain_free (struct chain_list *list); + +#endif