00001 /* 00002 * Copyright 2008, 2009 Alexandros Frantzis, Michael Iatrou 00003 * 00004 * This file is part of libbls. 00005 * 00006 * libbls is free software: you can redistribute it and/or modify it under the 00007 * terms of the GNU Lesser General Public License as published by the Free Software 00008 * Foundation, either version 3 of the License, or (at your option) any later 00009 * version. 00010 * 00011 * libbls is distributed in the hope that it will be useful, but WITHOUT ANY 00012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00013 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00014 * details. 00015 * 00016 * You should have received a copy of the GNU General Public License along with 00017 * libbls. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 /** 00021 * @file list.h 00022 * 00023 * List API 00024 */ 00025 #ifndef _BLESS_LIST_H 00026 #define _BLESS_LIST_H 00027 00028 #ifdef __cplusplus 00029 extern "C" { 00030 #endif 00031 00032 #include <sys/types.h> 00033 00034 /** 00035 * Iterate safely through the nodes in a list. 00036 * 00037 * This macro should be used when nodes are going to be altered or 00038 * deleted during the iteration. 00039 * 00040 * @param first the list node to start from 00041 * @param node a struct list_node pointer that will hold the current node in 00042 * each iteration 00043 * @param tmp a struct list_node pointer that will be used internally for safe 00044 * iteration 00045 */ 00046 #define list_for_each_safe(first, node, tmp) \ 00047 for ((node) = (first), (tmp) = (node)->next; (node) != (node)->next; \ 00048 (node) = (tmp), (tmp) = (tmp)->next) 00049 00050 /** 00051 * Reverse iterate safely through the nodes in a list. 00052 * 00053 * This macro should be used when nodes are going to be altered or 00054 * deleted during the iteration. 00055 * 00056 * @param last the list node to start from 00057 * @param node a struct list_node pointer that will hold the current node in 00058 * each iteration 00059 * @param tmp a struct list_node pointer that will be used internally for safe 00060 * iteration 00061 */ 00062 #define list_for_each_reverse_safe(last, node, tmp) \ 00063 for ((node) = (last), (tmp) = (node)->prev; (node) != (node)->prev; \ 00064 (node) = (tmp), (tmp) = (tmp)->prev) 00065 00066 /** 00067 * Iterate through the nodes in a list. 00068 * 00069 * If nodes are going to be altered or deleted during the iteration use 00070 * list_for_each_safe(). 00071 * 00072 * @param first the list node to start from 00073 * @param node a struct list_node pointer that will hold the current node in 00074 * each iteration 00075 */ 00076 #define list_for_each(first, node) \ 00077 for ((node) = (first); (node) != (node)->next; (node) = (node)->next) 00078 00079 /** 00080 * Reverse iterate through the nodes in a list. 00081 * 00082 * If nodes are going to be altered or deleted during the iteration use 00083 * list_for_each_reverse_safe(). 00084 * 00085 * @param last the list node to start from 00086 * @param node a struct list_node pointer that will hold the current node in 00087 * each iteration 00088 */ 00089 #define list_for_each_reverse(last, node) \ 00090 for ((node) = (last); (node) != (node)->prev; (node) = (node)->prev) 00091 00092 /** 00093 * Gets the entry containing a list node. 00094 * 00095 * @param ptr pointer to a struct list_node 00096 * @param type the type of the entry containing the list node 00097 * @param member the member of the type storing the list node 00098 * 00099 * @return a (type *) pointer to the entry 00100 */ 00101 #define list_entry(ptr, type, member) \ 00102 ((type *)_list_entry((ptr), (size_t)&((type *)0)->member)) 00103 00104 /** 00105 * Gets the entry containing a list node. 00106 * 00107 * @param ptr pointer to a struct list_node 00108 * @param ln_offset the offset in bytes in the entry the list node is stored at 00109 * 00110 * @return a (type *) pointer to the entry 00111 */ 00112 #define _list_entry(ptr, ln_offset) \ 00113 (void *)((char *)(ptr)-(ln_offset)) 00114 00115 /** 00116 * Creates a new list. 00117 * 00118 * @param[out] pptr pointer to the created list 00119 * @param type the type of the entry containing the list nodes 00120 * @param member the member of the type storing the list nodes 00121 * 00122 * @return the operation error code 00123 */ 00124 #define list_new(pptr, type, member) \ 00125 _list_new((pptr), (size_t)&((type *)0)->member) 00126 00127 00128 typedef struct list list_t; 00129 00130 struct list_node { 00131 struct list_node *next; 00132 struct list_node *prev; 00133 }; 00134 00135 int _list_new(list_t **list, size_t ln_offset); 00136 int list_free(list_t *list); 00137 00138 struct list_node *list_head(list_t *list); 00139 struct list_node *list_tail(list_t *list); 00140 00141 int list_insert_before(struct list_node *p, struct list_node *q); 00142 int list_insert_after(struct list_node *p, struct list_node *q); 00143 int list_insert_chain_after(struct list_node *p, struct list_node *start, 00144 struct list_node *end); 00145 int list_delete_chain(struct list_node *start, struct list_node *end); 00146 00147 #ifdef __cplusplus 00148 } 00149 #endif 00150 00151 #endif