Return free memory more aggressively.
[radsecproxy.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 /* allocates and initialises list structure; returns NULL if malloc fails */
9 struct list *list_create() {
10     struct list *list = malloc(sizeof(struct list));
11     if (list)
12         memset(list, 0, sizeof(struct list));
13     return list;
14 }
15
16 /* frees all memory associated with the list */
17 void list_destroy(struct list *list) {
18     struct list_node *node, *next;
19
20     if (!list)
21         return;
22
23     for (node = list->first; node; node = next) {
24         free(node->data);
25         next = node->next;
26         free(node);
27     }
28     free(list);
29 }
30
31 /* appends entry to list; returns 1 if ok, 0 if malloc fails */
32 int list_push(struct list *list, void *data) {
33     struct list_node *node;
34
35     node = malloc(sizeof(struct list_node));
36     if (!node)
37         return 0;
38
39     node->next = NULL;
40     node->data = data;
41
42     if (list->first)
43         list->last->next = node;
44     else
45         list->first = node;
46     list->last = node;
47
48     list->count++;
49     return 1;
50 }
51
52 /* removes first entry from list and returns data */
53 void *list_shift(struct list *list) {
54     struct list_node *node;
55     void *data;
56
57     if (!list || !list->first)
58         return NULL;
59
60     node = list->first;
61     list->first = node->next;
62     if (!list->first)
63         list->last = NULL;
64     data = node->data;
65     free(node);
66     list->count--;
67     return data;
68 }
69
70 /* removes all entries with matching data pointer */
71 void list_removedata(struct list *list, void *data) {
72     struct list_node *node, *t;
73
74     if (!list || !list->first)
75         return;
76
77     node = list->first;
78     while (node->data == data) {
79         list->first = node->next;
80         free(node);
81         list->count--;
82         node = list->first;
83         if (!node) {
84             list->last = NULL;
85             return;
86         }
87     }
88     for (; node->next; node = node->next)
89         if (node->next->data == data) {
90             t = node->next;
91             node->next = t->next;
92             free(t);
93             list->count--;
94             if (!node->next) { /* we removed the last one */
95                 list->last = node;
96                 return;
97             }
98         }
99 }
100
101 /* returns first node */
102 struct list_node *list_first(struct list *list) {
103     return list ? list->first : NULL;
104 }
105
106 /* returns the next node after the argument */
107 struct list_node *list_next(struct list_node *node) {
108     return node->next;
109 }
110
111 /* returns number of nodes */
112 uint32_t list_count(struct list *list) {
113     return list->count;
114 }
115
116 /* Local Variables: */
117 /* c-file-style: "stroustrup" */
118 /* End: */