list.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*
  2. * @file list.h
  3. * @brief Doubly-linked list
  4. * @copyright (c) 2009, Jouni Malinen <j@w1.fi>
  5. *
  6. * @note This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * Alternatively, this software may be distributed under the terms of BSD
  11. * license.
  12. *
  13. * See README and COPYING for more details.
  14. */
  15. #ifndef COMMON_LIST_H
  16. #define COMMON_LIST_H
  17. #include <stdio.h>
  18. /** struct dl_list - Doubly-linked list */
  19. struct dl_list {
  20. struct dl_list *next; /**< pointer to the next */
  21. struct dl_list *prev; /**< pointer to the previous */
  22. };
  23. /**
  24. * @defgroup System_APIs System APIs
  25. * @brief System APIs
  26. */
  27. /**
  28. * @addtogroup System_APIs
  29. * @{
  30. */
  31. /**
  32. * @defgroup DLIST_APIs DLIST APIs
  33. * @brief Double listed APIs
  34. */
  35. /**
  36. * @addtogroup DLIST_APIs
  37. * @{
  38. */
  39. /**
  40. * @brief reinitialize the list
  41. *
  42. * @param[in] *list the list
  43. *
  44. * @return None
  45. *
  46. * @note None
  47. */
  48. static __inline void dl_list_init(struct dl_list *list)
  49. {
  50. list->next = list;
  51. list->prev = list;
  52. }
  53. /**
  54. * @brief Insert a new entry after the specified head
  55. *
  56. * @param[in] *list list head to add it after
  57. * @param[in] *item new entry to be added
  58. *
  59. * @return None
  60. *
  61. * @note None
  62. */
  63. static __inline void dl_list_add(struct dl_list *list, struct dl_list *item)
  64. {
  65. item->next = list->next;
  66. item->prev = list;
  67. list->next->prev = item;
  68. list->next = item;
  69. }
  70. /**
  71. * @brief Insert a new entry before the specified head
  72. *
  73. * @param[in] *list list head to add it after
  74. * @param[in] *item new entry to be added
  75. *
  76. * @return None
  77. *
  78. * @note None
  79. */
  80. static __inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item)
  81. {
  82. dl_list_add(list->prev, item);
  83. }
  84. /**
  85. * @brief deletes entry from list
  86. *
  87. * @param[in] *item the element to delete from the list
  88. *
  89. * @return None
  90. *
  91. * @note None
  92. */
  93. static __inline void dl_list_del(struct dl_list *item)
  94. {
  95. item->next->prev = item->prev;
  96. item->prev->next = item->next;
  97. item->next = NULL;
  98. item->prev = NULL;
  99. }
  100. /**
  101. * @brief tests whether a list is empty
  102. *
  103. * @param[in] *list the list to test
  104. *
  105. * @retval 0 not empty
  106. * @retval 1 empty
  107. *
  108. * @note None
  109. */
  110. static __inline int dl_list_empty(struct dl_list *list)
  111. {
  112. return list->next == list;
  113. }
  114. /**
  115. * @brief count length of the list
  116. *
  117. * @param[in] *list the list to count
  118. *
  119. * @return length
  120. *
  121. * @note None
  122. */
  123. static __inline unsigned int dl_list_len(struct dl_list *list)
  124. {
  125. struct dl_list *item;
  126. int count = 0;
  127. for (item = list->next; item != list; item = item->next)
  128. count++;
  129. return count;
  130. }
  131. /**
  132. * @}
  133. */
  134. /**
  135. * @}
  136. */
  137. #ifndef offsetof
  138. /** offset address of the struct member */
  139. #define offsetof(type, member) ((long) &((type *) 0)->member)
  140. #endif
  141. /**
  142. * @brief get the struct for this entry
  143. *
  144. * @param[in] item the &struct list_head pointer
  145. * @param[in] type the type of the struct this is embedded in
  146. * @param[in] member the name of the list_struct within the struct
  147. *
  148. * @return pointer to the struct for this entry
  149. *
  150. * @note None
  151. */
  152. #define dl_list_entry(item, type, member) \
  153. ((type *) ((char *) item - offsetof(type, member)))
  154. /**
  155. * @brief get the first element from a list
  156. *
  157. * @param[in] list the list head to take the element from
  158. * @param[in] type the type of the struct this is embedded in
  159. * @param[in] member the name of the list_struct within the struct
  160. *
  161. * @return pointer to the first element from a list
  162. *
  163. * @note None
  164. */
  165. #define dl_list_first(list, type, member) \
  166. (dl_list_empty((list)) ? NULL : \
  167. dl_list_entry((list)->next, type, member))
  168. /**
  169. * @brief get the last element from a list
  170. *
  171. * @param[in] list the list head to take the element from
  172. * @param[in] type the type of the struct this is embedded in
  173. * @param[in] member the name of the list_struct within the struct
  174. *
  175. * @return pointer to the last element from a list
  176. *
  177. * @note None
  178. */
  179. #define dl_list_last(list, type, member) \
  180. (dl_list_empty((list)) ? NULL : \
  181. dl_list_entry((list)->prev, type, member))
  182. /**
  183. * @brief iterate over list of given type
  184. *
  185. * @param[in] item a loop cursor
  186. * @param[in] list the head for your list
  187. * @param[in] type struct type
  188. * @param[in] member the name of the list_struct within the struct
  189. *
  190. * @return None
  191. *
  192. * @note None
  193. */
  194. #define dl_list_for_each(item, list, type, member) \
  195. for (item = dl_list_entry((list)->next, type, member); \
  196. &item->member != (list); \
  197. item = dl_list_entry(item->member.next, type, member))
  198. /**
  199. * @brief iterate over list of given type safe against removal of list entry
  200. *
  201. * @param[in] item a loop cursor
  202. * @param[in] n temporary storage
  203. * @param[in] list the head for your list
  204. * @param[in] type struct type
  205. * @param[in] member the name of the list_struct within the struct
  206. *
  207. * @return None
  208. *
  209. * @note None
  210. */
  211. #define dl_list_for_each_safe(item, n, list, type, member) \
  212. for (item = dl_list_entry((list)->next, type, member), \
  213. n = dl_list_entry(item->member.next, type, member); \
  214. &item->member != (list); \
  215. item = n, n = dl_list_entry(n->member.next, type, member))
  216. /**
  217. * @brief iterate backwards over list of given type
  218. *
  219. * @param[in] item a loop cursor
  220. * @param[in] list the head for your list
  221. * @param[in] type struct type
  222. * @param[in] member the name of the list_struct within the struct
  223. *
  224. * @return None
  225. *
  226. * @note None
  227. */
  228. #define dl_list_for_each_reverse(item, list, type, member) \
  229. for (item = dl_list_entry((list)->prev, type, member); \
  230. &item->member != (list); \
  231. item = dl_list_entry(item->member.prev, type, member))
  232. /** define the list head */
  233. #define DEFINE_DL_LIST(name) \
  234. struct dl_list name = { &(name), &(name) }
  235. /**
  236. * @brief iterate over list of given type
  237. *
  238. * @param[in] item the type * to use as a loop cursor
  239. * @param[in] list the head for your list
  240. * @param[in] member the name of the list_struct within the struct
  241. *
  242. * @return None
  243. *
  244. * @note None
  245. */
  246. #define __dl_list_for_each(item, list, member) \
  247. for (item = dl_list_entry((list)->next, typeof(*(item)), member); \
  248. &item->member != (list); \
  249. item = dl_list_entry(item->member.next, typeof(*(item)), member))
  250. /**
  251. * @brief iterate over list of given type safe against removal of list entry
  252. *
  253. * @param[in] item the type * to use as a loop cursor
  254. * @param[in] n temporary storage
  255. * @param[in] list the head for your list
  256. * @param[in] member the name of the list_struct within the struct
  257. *
  258. * @return None
  259. *
  260. * @note None
  261. */
  262. #define __dl_list_for_each_safe(item, n, list, member) \
  263. for (item = dl_list_entry((list)->next, typeof(*(item)), member), \
  264. n = dl_list_entry(item->member.next, typeof(*(item)), member); \
  265. &item->member != (list); \
  266. item = n, n = dl_list_entry(n->member.next, typeof(*(item)), member))
  267. /**
  268. * @brief iterate backwards over list of given type
  269. *
  270. * @param[in] item the type * to use as a loop cursor
  271. * @param[in] list the head for your list
  272. * @param[in] member the name of the list_struct within the struct
  273. *
  274. * @return None
  275. *
  276. * @note None
  277. */
  278. #define __dl_list_for_each_reverse(item, list, member) \
  279. for (item = dl_list_entry((list)->prev, typeof(*(item)), member); \
  280. &item->member != (list); \
  281. item = dl_list_entry(item->member.prev, typeof(*(item)), member))
  282. /**
  283. * @}
  284. */
  285. /**
  286. * @}
  287. */
  288. #endif /* LIST_H */