void_list.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* void_list.c - the opkg package management system
  2. Carl D. Worth
  3. Copyright (C) 2001 University of Southern California
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License as
  6. published by the Free Software Foundation; either version 2, or (at
  7. your option) any later version.
  8. This program is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. */
  13. #include "void_list.h"
  14. #include "libbb/libbb.h"
  15. void void_list_elt_init(void_list_elt_t * elt, void *data)
  16. {
  17. INIT_LIST_HEAD(&elt->node);
  18. elt->data = data;
  19. }
  20. static void_list_elt_t *void_list_elt_new(void *data)
  21. {
  22. void_list_elt_t *elt;
  23. /* freed in void_list_elt_deinit */
  24. elt = xcalloc(1, sizeof(void_list_elt_t));
  25. void_list_elt_init(elt, data);
  26. return elt;
  27. }
  28. void void_list_elt_deinit(void_list_elt_t * elt)
  29. {
  30. list_del_init(&elt->node);
  31. void_list_elt_init(elt, NULL);
  32. free(elt);
  33. }
  34. void void_list_init(void_list_t * list)
  35. {
  36. INIT_LIST_HEAD(&list->head);
  37. }
  38. void void_list_deinit(void_list_t * list)
  39. {
  40. void_list_elt_t *elt;
  41. while (!void_list_empty(list)) {
  42. elt = void_list_pop(list);
  43. void_list_elt_deinit(elt);
  44. }
  45. INIT_LIST_HEAD(&list->head);
  46. }
  47. void void_list_append(void_list_t * list, void *data)
  48. {
  49. void_list_elt_t *elt = void_list_elt_new(data);
  50. list_add_tail(&elt->node, &list->head);
  51. }
  52. void void_list_push(void_list_t * list, void *data)
  53. {
  54. void_list_elt_t *elt = void_list_elt_new(data);
  55. list_add(&elt->node, &list->head);
  56. }
  57. void_list_elt_t *void_list_pop(void_list_t * list)
  58. {
  59. struct list_head *node;
  60. if (void_list_empty(list))
  61. return NULL;
  62. node = list->head.next;
  63. list_del_init(node);
  64. return list_entry(node, void_list_elt_t, node);
  65. }
  66. void *void_list_remove(void_list_t * list, void_list_elt_t ** iter)
  67. {
  68. void_list_elt_t *pos, *n;
  69. void_list_elt_t *old_elt;
  70. void *old_data = NULL;
  71. old_elt = *iter;
  72. if (!old_elt)
  73. return old_data;
  74. old_data = old_elt->data;
  75. list_for_each_entry_safe(pos, n, &list->head, node) {
  76. if (pos == old_elt)
  77. break;
  78. }
  79. if (pos != old_elt) {
  80. opkg_msg(ERROR, "Internal error: element not found in list.\n");
  81. return NULL;
  82. }
  83. *iter = list_entry(pos->node.prev, void_list_elt_t, node);
  84. void_list_elt_deinit(pos);
  85. return old_data;
  86. }
  87. /* remove element containing elt data, using cmp(elt->data, target_data) == 0. */
  88. void *void_list_remove_elt(void_list_t * list, const void *target_data,
  89. void_list_cmp_t cmp)
  90. {
  91. void_list_elt_t *pos, *n;
  92. void *old_data = NULL;
  93. list_for_each_entry_safe(pos, n, &list->head, node) {
  94. if (pos->data && cmp(pos->data, target_data) == 0) {
  95. old_data = pos->data;
  96. void_list_elt_deinit(pos);
  97. break;
  98. }
  99. }
  100. return old_data;
  101. }
  102. void_list_elt_t *void_list_first(void_list_t * list)
  103. {
  104. struct list_head *elt;
  105. if (!list)
  106. return NULL;
  107. elt = list->head.next;
  108. if (elt == &list->head) {
  109. return NULL;
  110. }
  111. return list_entry(elt, void_list_elt_t, node);
  112. }
  113. void_list_elt_t *void_list_prev(void_list_t * list, void_list_elt_t * node)
  114. {
  115. struct list_head *elt;
  116. if (!list || !node)
  117. return NULL;
  118. elt = node->node.prev;
  119. if (elt == &list->head) {
  120. return NULL;
  121. }
  122. return list_entry(elt, void_list_elt_t, node);
  123. }
  124. void_list_elt_t *void_list_next(void_list_t * list, void_list_elt_t * node)
  125. {
  126. struct list_head *elt;
  127. if (!list || !node)
  128. return NULL;
  129. elt = node->node.next;
  130. if (elt == &list->head) {
  131. return NULL;
  132. }
  133. return list_entry(elt, void_list_elt_t, node);
  134. }
  135. void_list_elt_t *void_list_last(void_list_t * list)
  136. {
  137. struct list_head *elt;
  138. if (!list)
  139. return NULL;
  140. elt = list->head.prev;
  141. if (elt == &list->head) {
  142. return NULL;
  143. }
  144. return list_entry(elt, void_list_elt_t, node);
  145. }