99d4e13493dca594535cbc8de13659c706d2f96b
[radsecproxy.git] / list.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include "list.h"
4
5 /* allocates and initialises list structure; returns NULL if malloc fails */
6 struct list *list_create() {
7     struct list *list = malloc(sizeof(struct list));
8     if (list)
9         memset(list, 0, sizeof(struct list));
10     return list;
11 }
12
13 /* frees all memory associated with the list */
14 void list_destroy(struct list *list) {
15     struct list_node *node, *next;
16
17     if (!list)
18         return;
19     
20     for (node = list->first; node; node = next) {
21         free(node->data);
22         next = node->next;
23         free(node);
24     }
25     free(list);
26 }
27
28 /* appends entry to list; returns 1 if ok, 0 if malloc fails */
29 int list_push(struct list *list, void *data) {
30     struct list_node *node;
31
32     node = malloc(sizeof(struct list_node));
33     if (!node)
34         return 0;
35     
36     node->next = NULL;
37     node->data = data;
38
39     if (list->first)
40         list->last->next = node;
41     else
42         list->first = node;
43     list->last = node;
44     
45     return 1;
46 }
47
48 /* removes first entry from list and returns data */
49 void *list_shift(struct list *list) {
50     struct list_node *node;
51     void *data;
52     
53     if (!list->first)
54         return NULL;
55     
56     node = list->first;
57     list->first = node->next;
58     if (!list->first)
59         list->last = NULL;
60     data = node->data;
61     free(node);
62     
63     return data;
64 }
65
66 /* removes all entries with matching data pointer */
67 void list_removedata(struct list *list, void *data) {
68     struct list_node *node, *t;
69     
70     if (!list || !list->first)
71         return;
72
73     node = list->first;
74     while (node->data == data) {
75         list->first = node->next;
76         free(node);
77         node = list->first;
78         if (!node) {
79             list->last = NULL;
80             return;
81         }
82     }
83     for (; node->next; node = node->next)
84         if (node->next->data == data) {
85             t = node->next;
86             node->next = t->next;
87             free(t);
88             if (!node->next) { /* we removed the last one */
89                 list->last = node;
90                 return;
91             }
92         }
93 }
94
95 /* returns first node */
96 struct list_node *list_first(struct list *list) {
97     return list ? list->first : NULL;
98 }
99
100 /* returns the next node after the argument */
101 struct list_node *list_next(struct list_node *node) {
102     return node->next;
103 }