aboutsummaryrefslogtreecommitdiff
path: root/src/common/list.c
blob: 00c18eee19c911f47bfd73deda666cde2369820e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "../include/list.h"
#include "../include/helpers.h"

node_t *init_node(void *x) {
  node_t *n = safe_calloc(1, sizeof(node_t));
  n->item = x;
  n->next = NULL;
  n->prev = NULL;
  return n;
}

list_t *init_list() {
  list_t *l = safe_calloc(1, sizeof(list_t));
  l->head = NULL;
  l->tail = NULL;
  l->size = 0;
  return l;
}

void *list_pop_front(list_t *l) {
  node_t *front = l->head;
  if (!front)
    return NULL;

  node_t *new = front->next;
  l->head = new;

  if (!new)
    l->tail = NULL;

  l->size--;
  return front;
}

void list_push_back(list_t *l, void *x) {
  node_t *back = l->tail;
  node_t *new = init_node(x);
  if (!back) {
    l->head = new;
    l->tail = l->head;
  } else {
    back->next = new;
    new->prev = back;
    l->tail = new;
  }
  l->size++;
}

void list_push_front(list_t *l, void *x) {
  node_t *front = l->head;
  node_t *new = init_node(x);
  if (!front) {
    l->tail = new;
    l->head = l->tail;
  } else {
    front->prev = new;
    new->next = front;
    l->head = new;
  }
  l->size++;
}

void list_free(void *x, void (*freefunc)(void *)) {
  list_t *l = x;
  node_t *cur = l->head;
  node_t *tmp;

  if (!x)
    return;

  while (cur) {
    freefunc(cur->item);
    tmp = cur->next;
    free(cur);
    cur = tmp;
  }
  free(l);
}