list.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include <string.h>
  2. #include "list.h"
  3. void
  4. list_init(List *list, Disposer *disposer)
  5. {
  6. list->len = 0;
  7. list->disposer = disposer;
  8. list->head = list->tail = NULL;
  9. }
  10. void
  11. list_dispose(List *list)
  12. {
  13. void *data;
  14. while(!list_remove(list, NULL, &data))
  15. if (list->disposer)
  16. list->disposer->dispose(data, list->disposer->extra);
  17. }
  18. Nit_error
  19. list_add(List *list, List_entry *prev, const void *data)
  20. {
  21. List_entry *entry = malloc(sizeof(*entry));
  22. if (!entry)
  23. return NIT_ERROR_MEMORY;
  24. entry->data = (void *) data;
  25. if (!prev) {
  26. entry->next = list->head;
  27. list->head = entry;
  28. if (!list->tail)
  29. list->tail = entry;
  30. } else {
  31. entry->next = prev->next;
  32. prev->next = entry;
  33. if (!entry->next)
  34. list->tail = entry;
  35. }
  36. ++list->len;
  37. return NIT_ERROR_FINE;
  38. }
  39. Nit_error
  40. list_remove(List *list, List_entry *prev, void **data)
  41. {
  42. List_entry *old_entry;
  43. if (!list->len)
  44. return NIT_ERROR_EMPTY;
  45. if (!prev) {
  46. *data = list->head->data;
  47. old_entry = list->head;
  48. list->head = list->head->next;
  49. if (list->len == 1)
  50. list->tail = NULL;
  51. } else {
  52. if (!prev->next)
  53. return NIT_ERROR_NO_NEXT;
  54. *data = prev->next->data;
  55. old_entry = prev->next;
  56. prev->next = prev->next->next;
  57. if (!prev->next)
  58. list->tail = prev;
  59. }
  60. free(old_entry);
  61. --list->len;
  62. return NIT_ERROR_FINE;
  63. }
  64. void **
  65. list_peek(List *list)
  66. {
  67. return list->head ? &list->head->data : NULL;
  68. }