list.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 1997-2002 Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15. * PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. /*!
  18. * $ISC: list.h,v 1.18.2.2.8.1 2004/03/06 08:14:43 marka Exp $
  19. * $Id$
  20. * Slightly modified for uHTTP.
  21. */
  22. #ifndef ISC_LIST_H
  23. #define ISC_LIST_H 1
  24. /*!
  25. * \addtogroup xgIscList Linked list macros
  26. * \ingroup xgUHTTPUtils
  27. */
  28. /*@{*/
  29. #ifdef ISC_LIST_CHECKINIT
  30. #define ISC_LINK_INSIST(x) ISC_INSIST(x)
  31. #else
  32. #define ISC_LINK_INSIST(x)
  33. #endif
  34. #define ISC_LIST(type) struct { type *head, *tail; }
  35. #define ISC_LIST_INIT(list) \
  36. do { (list).head = NULL; (list).tail = NULL; } while (0)
  37. #define ISC_LINK(type) struct { type *prev, *next; }
  38. #define ISC_LINK_INIT_TYPE(elt, link, type) \
  39. do { \
  40. (elt)->link.prev = (type *)(-1); \
  41. (elt)->link.next = (type *)(-1); \
  42. } while (0)
  43. #define ISC_LINK_INIT(elt, link) \
  44. ISC_LINK_INIT_TYPE(elt, link, void)
  45. #define ISC_LINK_LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1))
  46. #define ISC_LIST_HEAD(list) ((list).head)
  47. #define ISC_LIST_TAIL(list) ((list).tail)
  48. #define ISC_LIST_EMPTY(list) ISC_TF((list).head == NULL)
  49. #define __ISC_LIST_PREPENDUNSAFE(list, elt, link) \
  50. do { \
  51. if ((list).head != NULL) \
  52. (list).head->link.prev = (elt); \
  53. else \
  54. (list).tail = (elt); \
  55. (elt)->link.prev = NULL; \
  56. (elt)->link.next = (list).head; \
  57. (list).head = (elt); \
  58. } while (0)
  59. #define ISC_LIST_PREPEND(list, elt, link) \
  60. do { \
  61. ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
  62. __ISC_LIST_PREPENDUNSAFE(list, elt, link); \
  63. } while (0)
  64. #define ISC_LIST_INITANDPREPEND(list, elt, link) \
  65. __ISC_LIST_PREPENDUNSAFE(list, elt, link)
  66. #define __ISC_LIST_APPENDUNSAFE(list, elt, link) \
  67. do { \
  68. if ((list).tail != NULL) \
  69. (list).tail->link.next = (elt); \
  70. else \
  71. (list).head = (elt); \
  72. (elt)->link.prev = (list).tail; \
  73. (elt)->link.next = NULL; \
  74. (list).tail = (elt); \
  75. } while (0)
  76. #define ISC_LIST_APPEND(list, elt, link) \
  77. do { \
  78. ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
  79. __ISC_LIST_APPENDUNSAFE(list, elt, link); \
  80. } while (0)
  81. #define ISC_LIST_INITANDAPPEND(list, elt, link) \
  82. __ISC_LIST_APPENDUNSAFE(list, elt, link)
  83. #define __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type) \
  84. do { \
  85. if ((elt)->link.next != NULL) \
  86. (elt)->link.next->link.prev = (elt)->link.prev; \
  87. else \
  88. (list).tail = (elt)->link.prev; \
  89. if ((elt)->link.prev != NULL) \
  90. (elt)->link.prev->link.next = (elt)->link.next; \
  91. else \
  92. (list).head = (elt)->link.next; \
  93. (elt)->link.prev = (type *)(-1); \
  94. (elt)->link.next = (type *)(-1); \
  95. } while (0)
  96. #define __ISC_LIST_UNLINKUNSAFE(list, elt, link) \
  97. __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void)
  98. #define ISC_LIST_UNLINK_TYPE(list, elt, link, type) \
  99. do { \
  100. ISC_LINK_INSIST(ISC_LINK_LINKED(elt, link)); \
  101. __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type); \
  102. } while (0)
  103. #define ISC_LIST_UNLINK(list, elt, link) \
  104. ISC_LIST_UNLINK_TYPE(list, elt, link, void)
  105. #define ISC_LIST_PREV(elt, link) ((elt)->link.prev)
  106. #define ISC_LIST_NEXT(elt, link) ((elt)->link.next)
  107. #define __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link) \
  108. do { \
  109. if ((before)->link.prev == NULL) \
  110. ISC_LIST_PREPEND(list, elt, link); \
  111. else { \
  112. (elt)->link.prev = (before)->link.prev; \
  113. (before)->link.prev = (elt); \
  114. (elt)->link.prev->link.next = (elt); \
  115. (elt)->link.next = (before); \
  116. } \
  117. } while (0)
  118. #define ISC_LIST_INSERTBEFORE(list, before, elt, link) \
  119. do { \
  120. ISC_LINK_INSIST(ISC_LINK_LINKED(before, link)); \
  121. ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
  122. __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link); \
  123. } while (0)
  124. #define __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link) \
  125. do { \
  126. if ((after)->link.next == NULL) \
  127. ISC_LIST_APPEND(list, elt, link); \
  128. else { \
  129. (elt)->link.next = (after)->link.next; \
  130. (after)->link.next = (elt); \
  131. (elt)->link.next->link.prev = (elt); \
  132. (elt)->link.prev = (after); \
  133. } \
  134. } while (0)
  135. #define ISC_LIST_INSERTAFTER(list, after, elt, link) \
  136. do { \
  137. ISC_LINK_INSIST(ISC_LINK_LINKED(after, link)); \
  138. ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
  139. __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link); \
  140. } while (0)
  141. #define ISC_LIST_APPENDLIST(list1, list2, link) \
  142. do { \
  143. if (ISC_LIST_EMPTY(list1)) \
  144. (list1) = (list2); \
  145. else if (!ISC_LIST_EMPTY(list2)) { \
  146. (list1).tail->link.next = (list2).head; \
  147. (list2).head->link.prev = (list1).tail; \
  148. (list1).tail = (list2).tail; \
  149. } \
  150. (list2).head = NULL; \
  151. (list2).tail = NULL; \
  152. } while (0)
  153. #define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link)
  154. #define __ISC_LIST_ENQUEUEUNSAFE(list, elt, link) \
  155. __ISC_LIST_APPENDUNSAFE(list, elt, link)
  156. #define ISC_LIST_DEQUEUE(list, elt, link) \
  157. ISC_LIST_UNLINK_TYPE(list, elt, link, void)
  158. #define ISC_LIST_DEQUEUE_TYPE(list, elt, link, type) \
  159. ISC_LIST_UNLINK_TYPE(list, elt, link, type)
  160. #define __ISC_LIST_DEQUEUEUNSAFE(list, elt, link) \
  161. __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void)
  162. #define __ISC_LIST_DEQUEUEUNSAFE_TYPE(list, elt, link, type) \
  163. __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type)
  164. #define ISC_LIST_INITIAL_TYPE(type) { (type *)NULL, (type *)NULL }
  165. #define ISC_LIST_INITIAL ISC_LIST_INITIAL_TYPE(void)
  166. #define ISC_LINK_INITIAL(type) { (type *)-1, (type *)-1 }
  167. /*@}*/
  168. #endif /* ISC_LIST_H */