add scc and update other code
[ccc.git] / list.c
diff --git a/list.c b/list.c
new file mode 100644 (file)
index 0000000..62af95e
--- /dev/null
+++ b/list.c
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "list.h"
+#include "util.h"
+
+struct list *list_append(void *el, struct list *head)
+{
+       if (head == NULL)
+               return list_cons(el, NULL);
+       struct list *tail = head;
+       while (tail->tail != NULL)
+               tail = tail->tail;
+       tail->tail = list_cons(el, NULL);
+       return head;
+}
+
+struct list *list_cons(void *el, struct list *tail)
+{
+       struct list *res = safe_malloc(sizeof(struct list));
+       res->el = el;
+       res->tail = tail;
+       return res;
+}
+
+void list_free(struct list *head, void (*freefun)(void *))
+{
+       while (head != NULL) {
+               struct list *t = head;
+               if (freefun != NULL)
+                       freefun(head->el);
+               head = head->tail;
+               free(t);
+       }
+}
+
+void **list_to_array(struct list *list, int *num, bool reverse)
+{
+       int i = list_length(list);
+       *num = i;
+       void **ptr = safe_malloc(i*sizeof(void *));
+
+       struct list *r = list;
+       while(i > 0) {
+               if (reverse)
+                       ptr[--i] = r->el;
+               else
+                       ptr[*num-(--i)-1] = r->el;
+               struct list *t = r;
+               r = r->tail;
+               free(t);
+       }
+       return ptr;
+}
+
+int list_length(struct list *r)
+{
+       int i = 0;
+       FOREACH(e, r)
+               i++;
+       return i;
+}