PageRenderTime 60ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/Chapter_06_Shell/00_Start/lib/list.c

https://github.com/l30nard0/os4ec
C | 214 lines | 142 code | 40 blank | 32 comment | 45 complexity | 0dd9d5dd7479a68519d5f094270ef4da MD5 | raw file
  1. /*! List manipulation functions
  2. *
  3. * Double linked lists are used
  4. * List header points to first and last list element
  5. */
  6. #include "list.h"
  7. #include <lib/types.h>
  8. #include <kernel/errno.h>
  9. void list_init ( list_t *list )
  10. {
  11. ASSERT ( list );
  12. list->first = list->last = NULL;
  13. }
  14. /*! Add element to list, add to tail - as last element */
  15. void list_append ( list_t *list, void *object, list_h *hdr )
  16. {
  17. ASSERT ( list && object && hdr );
  18. hdr->object = object; /* save reference to object */
  19. hdr->next = NULL; /* put it at list end (as last element) */
  20. if ( list->first )
  21. {
  22. list->last->next = hdr;
  23. hdr->prev = list->last;
  24. list->last = hdr;
  25. }
  26. else {
  27. list->first = list->last = hdr;
  28. hdr->prev = NULL;
  29. }
  30. }
  31. /*! Add element to list, add to head - as first element */
  32. void list_prepend ( list_t *list, void *object, list_h *hdr )
  33. {
  34. ASSERT ( list && object && hdr );
  35. hdr->object = object; /* save reference to object */
  36. hdr->prev = NULL; /* put it at list start (as first element) */
  37. hdr->next = list->first;
  38. if ( list->first )
  39. list->first->prev = hdr; /* list was not empty */
  40. else
  41. list->last = hdr; /* list was empty */
  42. list->first = hdr;
  43. }
  44. /*! Add element to sorted list */
  45. void list_sort_add ( list_t *list, void *object, list_h *hdr,
  46. int (*cmp) ( void *, void * ) )
  47. {
  48. list_h *iter;
  49. ASSERT ( list && object && hdr && cmp );
  50. hdr->object = object; /* save reference to object */
  51. /* speedup search if elem is to be last in list */
  52. if ( list->last && cmp ( object, list->last->object ) >= 0 )
  53. iter = NULL; /* insert after last */
  54. else
  55. iter = list->first; /* start searching from beginning */
  56. while ( iter && cmp ( object, iter->object ) >= 0 )
  57. iter = iter->next;
  58. /* insert before 'iter' */
  59. hdr->next = iter;
  60. if ( iter )
  61. {
  62. hdr->prev = iter->prev;
  63. if ( iter->prev )
  64. iter->prev->next = hdr;
  65. else
  66. list->first = hdr; /* 'iter' was first in list */
  67. iter->prev = hdr;
  68. }
  69. else {
  70. /* 'iter' == NULL => add to the end of list */
  71. if ( list->last )
  72. {
  73. /* list was not empty */
  74. hdr->prev = list->last;
  75. list->last->next = hdr;
  76. list->last = hdr;
  77. }
  78. else {
  79. /* list was empty */
  80. list->first = list->last = hdr;
  81. hdr->prev = NULL;
  82. }
  83. }
  84. }
  85. /*! Get pointer to first or last list element */
  86. void *list_get ( list_t *list, unsigned int flags )
  87. {
  88. list_h *hdr;
  89. ASSERT ( list );
  90. if ( flags & LAST )
  91. hdr = list->last;
  92. else
  93. hdr = list->first;
  94. if ( hdr )
  95. return hdr->object;
  96. else
  97. return NULL;
  98. }
  99. /*! Get pointer to next object in list */
  100. void *list_get_next ( list_h *hdr )
  101. {
  102. if ( !hdr || !hdr->next )
  103. return NULL;
  104. else
  105. return hdr->next->object;
  106. }
  107. /*!
  108. * Remove element from list
  109. * \param list List identifier (pointer)
  110. * \param flags Constant: FIRST(0) or LAST(1) - which element to remove from
  111. * list and return pointer to it
  112. * \param ref Reference (pointer) to element to be removed from list
  113. * \return pointer to removed list element, NULL if list is empty
  114. * NOTE function assumes that element is in list - it doesn't check!!!
  115. */
  116. void *list_remove ( list_t *list, unsigned int flags, list_h *ref )
  117. {
  118. list_h *hdr;
  119. ASSERT ( list );
  120. if ( ref )
  121. hdr = ref;
  122. else if ( flags & LAST )
  123. hdr = list->last;
  124. else
  125. hdr = list->first;
  126. if ( hdr )
  127. {
  128. if ( hdr->prev )
  129. hdr->prev->next = hdr->next;
  130. if ( hdr->next )
  131. hdr->next->prev = hdr->prev;
  132. if ( list->first == hdr )
  133. list->first = hdr->next;
  134. if ( list->last == hdr )
  135. list->last = hdr->prev;
  136. return hdr->object;
  137. }
  138. else {
  139. return NULL;
  140. }
  141. }
  142. /*!
  143. * Remove element from list if element is in list
  144. * \param list List identifier (pointer)
  145. * \param flags Constant: FIRST(0) or LAST(1) - which element to remove from
  146. * list and return pointer to it
  147. * \param ref Reference (pointer) to element to be removed from list
  148. * \return pointer to removed list element, NULL if list is empty
  149. */
  150. void *list_find_and_remove ( list_t *list, list_h *ref )
  151. {
  152. list_h *iter;
  153. ASSERT ( list && ref );
  154. iter = list->first;
  155. while ( iter )
  156. {
  157. if ( iter == ref )
  158. {
  159. if ( ref->prev )
  160. ref->prev->next = ref->next;
  161. if ( ref->next )
  162. ref->next->prev = ref->prev;
  163. if ( list->first == ref )
  164. list->first = ref->next;
  165. if ( list->last == ref )
  166. list->last = ref->prev;
  167. return ref->object;
  168. }
  169. else {
  170. iter = iter->next;
  171. }
  172. }
  173. return NULL;
  174. }