/lib/util/list.c

https://github.com/gonzoj/motoko · C · 242 lines · 107 code · 57 blank · 78 comment · 19 complexity · 70824fff8a4078888b31b432b80236b6 MD5 · raw file

  1. /*
  2. * Copyright (C) 2010 gonzoj
  3. *
  4. * Please check the CREDITS file for further information.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. //#include <pthread.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "util/list.h"
  23. struct list list_create(size_t sizeof_type) {
  24. struct list l;
  25. l = (struct list) { NULL, sizeof_type, 0 };
  26. //pthread_mutex_init(&l.mutex, NULL);
  27. return l;
  28. }
  29. bool list_empty(struct list *l) {
  30. return l->len ? FALSE : TRUE;
  31. }
  32. unsigned list_size(struct list *l) {
  33. return l->len;
  34. }
  35. bool list_add(struct list *l, void *e) {
  36. //pthread_mutex_lock(&l->mutex);
  37. l->elements = realloc(l->elements, ++l->len * l->size);
  38. if (l->elements) {
  39. memcpy(l->elements + (l->len - 1) * l->size, e, l->size);
  40. //pthread_mutex_unlock(&l->mutex);
  41. return TRUE;
  42. }
  43. //pthread_mutex_unlock(&l->mutex);
  44. return FALSE;
  45. }
  46. bool list_remove(struct list *l, void *e) {
  47. /*unsigned new_len = 0;
  48. void *i;
  49. void *tmp = NULL;
  50. int index;
  51. pthread_mutex_lock(&l->mutex);
  52. for (index = 0; index < l->len; index++) {
  53. i = l->elements + index * l->size;
  54. if (i != e) {
  55. tmp = realloc(tmp, l->size * ++new_len);
  56. if (!tmp) {
  57. pthread_mutex_unlock(&l->mutex);
  58. return FALSE;
  59. }
  60. memcpy(tmp + (new_len - 1) * l->size, i, l->size);
  61. }
  62. }
  63. free(l->elements);
  64. l->elements = tmp;
  65. l->len = new_len;
  66. pthread_mutex_unlock(&l->mutex);
  67. return TRUE;*/
  68. // optimized implementation
  69. //pthread_mutex_lock(&l->mutex);
  70. int offset = e - l->elements;
  71. if ((offset < 0) || (offset >= l->len * l->size) || (offset % l->size != 0)) {
  72. //pthread_mutex_unlock(&l->mutex);
  73. return FALSE;
  74. }
  75. void *tmp = NULL;
  76. if (--l->len > 0) {
  77. tmp = malloc(l->size * l->len);
  78. if (offset > 0) {
  79. memcpy(tmp, l->elements, offset);
  80. }
  81. if ((l->len * l->size) - offset > 0) {
  82. memcpy(tmp + offset, e + l->size, (l->len * l->size) - offset);
  83. }
  84. }
  85. free(l->elements);
  86. l->elements = tmp;
  87. //pthread_mutex_unlock(&l->mutex);
  88. return TRUE;
  89. }
  90. bool list_clear(struct list *l) {
  91. if (l->len) {
  92. free(l->elements);
  93. l->elements = NULL;
  94. l->len = 0;
  95. }
  96. //pthread_mutex_destroy(&l->mutex);
  97. return TRUE;
  98. }
  99. void list_sort(struct list *l, int (*comparator)(const void *, const void *)) {
  100. //pthread_mutex_lock(&l->mutex);
  101. qsort(l->elements, (size_t) l->len, l->size, comparator);
  102. //pthread_mutex_unlock(&l->mutex);
  103. }
  104. struct list * list_clone(struct list *l, struct list *c) {
  105. //struct list *c = (struct list *) malloc(sizeof(struct list));
  106. //pthread_mutex_lock(&l->mutex);
  107. c->len = l->len;
  108. c->size = l->size;
  109. c->elements = malloc(c->size * c->len);
  110. memcpy(c->elements, l->elements, c->size * c->len);
  111. //pthread_mutex_unlock(&l->mutex);
  112. //pthread_mutex_init(&c->mutex, NULL);
  113. return c;
  114. }
  115. // shouldn't be used
  116. void * list_iterate(struct list *l) {
  117. static int i = 0;
  118. static bool reset = TRUE;
  119. if (!l) {
  120. i = 0;
  121. reset = TRUE;
  122. return NULL;
  123. }
  124. if (!l->len || ((i && !(i % l->len)) && reset)) {
  125. reset = FALSE;
  126. return NULL;
  127. } else {
  128. reset = TRUE;
  129. return (l->elements + (i++ % l->len) * l->size);
  130. }
  131. }
  132. void * list_element(struct list *l, int index) {
  133. // return (index >= l->len) ? NULL : l->elements + index * l->size;
  134. void *e;
  135. //pthread_mutex_lock(&l->mutex);
  136. if (index >= l->len) {
  137. e = NULL;
  138. } else {
  139. //e = malloc(l->size);
  140. //memcpy(e, l->elements + index * l->size, l->size);
  141. e = l->elements + index * l->size;
  142. }
  143. //pthread_mutex_unlock(&l->mutex);
  144. return e;
  145. }
  146. void * list_find(struct list *l, int (*comparator)(const void *, const void *), void *e) {
  147. int index;
  148. //pthread_mutex_lock(&l->mutex);
  149. for (index = 0; index < l->len; index++) {
  150. void *i = l->elements + index * l->size;
  151. if (comparator(i, e)) {
  152. //i = malloc(l->size);
  153. //memcpy(i, l->elements + index * l->size, l->size);
  154. //pthread_mutex_unlock(&l->mutex);
  155. return i;
  156. }
  157. }
  158. //pthread_mutex_unlock(&l->mutex);
  159. return NULL;
  160. }
  161. struct iterator list_iterator(struct list *l) {
  162. return (struct iterator) { l, 0, NULL };
  163. }
  164. void * iterator_next(struct iterator *i) {
  165. /*if (i->element) {
  166. free(i->element);
  167. }*/
  168. i->element = list_element(i->list, i->index++);
  169. return i->element;
  170. }
  171. void iterator_remove(struct iterator *i) {
  172. list_remove(i->list, i->element);
  173. i->index--;
  174. }
  175. void iterator_destroy(struct iterator *i) {
  176. /*if (i->element) {
  177. free(i->element);
  178. }*/
  179. }