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