WIP: Fix the Proxy-State issue.
[libradsec.git] / list.c
1 /* Copyright (c) 2007-2009, UNINETT AS */
2 /* See LICENSE for licensing information. */
3
4 #include <stdlib.h>
5 #include <string.h>
6 #include "list.h"
7
8 /* Private helper functions. */
9 static void list_free_helper_(struct list *list, int free_data_flag) {
10     struct list_node *node, *next;
11
12     if (!list)
13         return;
14
15     for (node = list->first; node; node = next) {
16         if (free_data_flag)
17             free(node->data);
18         next = node->next;
19         free(node);
20     }
21     free(list);
22 }
23
24 /* Public functions. */
25
26 /* allocates and initialises list structure; returns NULL if malloc fails */
27 struct list *list_create() {
28     struct list *list = malloc(sizeof(struct list));
29     if (list)
30         memset(list, 0, sizeof(struct list));
31     return list;
32 }
33
34 /* frees all memory associated with the list
35    note that the data pointed at from each node is also freed
36    use list_free() to free only the memory used by the list itself */
37 void list_destroy(struct list *list) {
38     list_free_helper_(list, 1);
39 }
40
41 /* frees the meory used by the list itself
42    note that the data pointed at from each node is not freed
43    use list_destroy() to free all the data associated with the list */
44 void list_free(struct list *list) {
45     list_free_helper_(list, 0);
46 }
47
48 /* appends entry to list; returns 1 if ok, 0 if malloc fails */
49 int list_push(struct list *list, void *data) {
50     struct list_node *node;
51
52     node = malloc(sizeof(struct list_node));
53     if (!node)
54         return 0;
55
56     node->next = NULL;
57     node->data = data;
58
59     if (list->first)
60         list->last->next = node;
61     else
62         list->first = node;
63     list->last = node;
64
65     list->count++;
66     return 1;
67 }
68
69 /* removes first entry from list and returns data */
70 void *list_shift(struct list *list) {
71     struct list_node *node;
72     void *data;
73
74     if (!list || !list->first)
75         return NULL;
76
77     node = list->first;
78     list->first = node->next;
79     if (!list->first)
80         list->last = NULL;
81     data = node->data;
82     free(node);
83     list->count--;
84     return data;
85 }
86
87 /* removes all entries with matching data pointer */
88 void list_removedata(struct list *list, void *data) {
89     struct list_node *node, *t;
90
91     if (!list || !list->first)
92         return;
93
94     node = list->first;
95     while (node->data == data) {
96         list->first = node->next;
97         free(node);
98         list->count--;
99         node = list->first;
100         if (!node) {
101             list->last = NULL;
102             return;
103         }
104     }
105     for (; node->next; node = node->next)
106         if (node->next->data == data) {
107             t = node->next;
108             node->next = t->next;
109             free(t);
110             list->count--;
111             if (!node->next) { /* we removed the last one */
112                 list->last = node;
113                 return;
114             }
115         }
116 }
117
118 /* returns first node */
119 struct list_node *list_first(struct list *list) {
120     return list ? list->first : NULL;
121 }
122
123 /* returns the next node after the argument */
124 struct list_node *list_next(struct list_node *node) {
125     return node->next;
126 }
127
128 /* returns number of nodes */
129 uint32_t list_count(struct list *list) {
130     return list->count;
131 }
132
133 /* Local Variables: */
134 /* c-file-style: "stroustrup" */
135 /* End: */