A include/cobble/data/list.h => include/cobble/data/list.h +30 -0
@@ 0,0 1,30 @@
+/* see LICENSE for copyright and license details */
+#ifndef _COBBLE_LIST_H_
+#define _COBBLE_LIST_H_
+
+#include <stddef.h>
+
+#include <cobble/error.h>
+
+/* a doubly linked list */
+struct list_node {
+ void *data;
+
+ struct list_node *next;
+ struct list_node *prev;
+};
+
+struct list {
+ size_t len;
+ size_t e_size;
+
+ struct list_node *head;
+ struct list_node *tail;
+};
+
+CBL_ERROR list_new(struct list**, size_t);
+CBL_ERROR list_init(struct list*, size_t);
+void list_free(struct list**);
+void list_destroy(struct list*);
+
+#endif<
\ No newline at end of file
A src/data/list.c => src/data/list.c +49 -0
@@ 0,0 1,49 @@
+/* see LICENSE file for copyright and license details. */
+
+#include <stdlib.h>
+
+#include <cobble/data/list.h>
+
+CBL_ERROR
+list_new(struct list **l, size_t e_size)
+{
+ *l = malloc(sizeof(struct list));
+ if (!*l) return E_MALLOC;
+
+ return list_init(*l, e_size);
+}
+
+CBL_ERROR
+list_init(struct list *l, size_t e_size)
+{
+ l->e_size = e_size;
+ l->head = NULL;
+ l->tail = NULL;
+ l->len = 0;
+
+ return E_SUCCESS;
+}
+
+void
+list_free(struct list **l)
+{
+ if (!*l) return;
+
+ list_destroy(*l);
+ free(*l);
+}
+
+void
+list_destroy(struct list *l)
+{
+ struct list_node *node = l->head;
+
+ while (node) {
+ if (node->data) free(node->data);
+
+ struct list_node *tmp = node;
+ node = node->next;
+
+ free(tmp);
+ }
+}<
\ No newline at end of file