source: MondoRescue/branches/stable/mondo/src/lib/mr_list.c@ 1363

Last change on this file since 1363 was 1363, checked in by Bruno Cornec, 17 years ago

Update for the mr_list structure to have a pointer on function to remove data allocated in the structure mr_list_elt in the data field.

  • Property svn:eol-style set to native
File size: 4.4 KB
Line 
1/*
2 * $Id$
3 *
4 * List handling functions safe from a memory management point of view
5 *
6 */
7
8#include <stdio.h>
9#include <string.h>
10#include <time.h>
11
12#include "mr_list.h"
13
14/* List allocation and initialization */
15void mr_list_alloc(struct mr_list *list) {
16
17 list = mr_malloc(sizeof(struct mr_list));
18 list->first = NULL;
19 list->last = NULL;
20}
21
22/* Elt of list allocation and initialization */
23void mr_list_alloc_elt(struct mr_list_elt *elt, void *data, void (*mr_free_data)(void *data)) {
24
25 elt = mr_malloc(sizeof(struct mr_list_elt));
26 elt->mr_free_data = mr_free_data;
27 elt->data = (void *)data;
28 elt->prev = NULL;
29 elt->next = NULL;
30}
31
32void mr_list_free_elt(struct mr_list_elt *elt) {
33 elt->mr_free_data(elt->data);
34 mr_free(elt->data);
35 mr_free(elt);
36}
37
38/* List desallocation and removal */
39void mr_list_free(struct mr_list *list) {
40
41 struct mr_list_elt *elt = list->first;
42 struct mr_list_elt *elt2 = NULL;
43
44 while (elt != NULL) {
45 /* preserve next elt */
46 elt2 = elt->next;
47 /* Purge elt */
48 mr_list_free_elt(elt);
49 /* next elt to consider */
50 elt = elt2;
51 }
52
53 mr_free(list);
54}
55
56/* Count the number of elements in the list */
57int mr_list_length(struct mr_list *list) {
58
59 int i = 0;
60 struct mr_list_elt *p = list->first;
61
62 while (p != NULL) {
63 i++;
64 p = p->next;
65 }
66 return(i);
67}
68
69/* Add an element first in the list */
70void mr_list_add_elt_first(struct mr_list *list, struct mr_list_elt *elt) {
71
72 if (list->first != NULL) {
73 /* if there was a first elt shift it */
74 list->first->prev = elt;
75 elt->next = list->first;
76 } else {
77 /* if there was no first, there was no last as well, so set it up */
78 list->last = elt;
79 }
80 list->first = elt;
81}
82
83/* Add an element last in the list */
84void mr_list_add_elt_last(struct mr_list *list, struct mr_list_elt *elt) {
85
86 if (list->last != NULL) {
87 /* if there was a last elt use it */
88 list->last->next = elt;
89 elt->prev = list->last;
90 } else {
91 /* if there was no last, there was no first as well, so set it up */
92 list->first = elt;
93 }
94 list->last = elt;
95}
96
97/* Add an element in the list after the ref elt given in parameter */
98void mr_list_add_elt_after(struct mr_list *list, struct mr_list_elt *ref, struct mr_list_elt *elt) {
99
100 if (ref->next != NULL) {
101 /* if there was a next elt, shit it */
102 ref->next->prev = elt;
103 elt->next = ref->next;
104 } else {
105 /* If not, it's the last elt */
106 list->last = elt;
107 }
108 ref->next = elt;
109 elt->prev = ref;
110}
111
112/* Add an element in the list before the ref elt given in parameter */
113void mr_list_add_elt_before(struct mr_list *list, struct mr_list_elt *ref, struct mr_list_elt *elt) {
114
115 if (ref->prev != NULL) {
116 /* if there was a prev elt, shit it */
117 ref->prev->next = elt;
118 elt->prev = ref->prev;
119 } else {
120 /* If not, it's the first elt */
121 list->first = elt;
122 }
123 ref->prev = elt;
124 elt->next = ref;
125}
126
127/* Delete the first element in the list */
128void mr_list_del_elt_first(struct mr_list *list) {
129
130 struct mr_list_elt *elt = list->first;
131
132 if (elt->next != NULL) {
133 /* There are other elts behind */
134 list->first = elt->next;
135 }
136 mr_list_free_elt(elt);
137}
138
139/* Delete the last element in the list */
140void mr_list_del_elt_last(struct mr_list *list) {
141
142 struct mr_list_elt *elt = list->last;
143
144 if (elt->prev != NULL) {
145 /* There are other elts before */
146 list->last = elt->prev;
147 }
148 mr_list_free_elt(elt);
149}
150
151/* Delete an element in the list after the ref elt given in parameter */
152void mr_list_del_elt_after(struct mr_list *list, struct mr_list_elt *ref) {
153
154 struct mr_list_elt *elt = ref->next;
155
156 if (elt != NULL) {
157 /* if there was a next elt, delete it */
158 if (elt->next != NULL) {
159 /* there is an elt behind, shift it */
160 elt->prev->next = elt->next;
161 elt->next->prev = elt->prev;
162 mr_list_free_elt(elt);
163 } else {
164 /* that elt is the last one */
165 mr_list_del_elt_last(list);
166 }
167 } else {
168 /* If not, ref is the last elt */
169 mr_msg(3, "No elt to delete available after the last one");
170 }
171}
172
173/* Delete an element in the list before the ref elt given in parameter */
174void mr_list_del_elt_before(struct mr_list *list, struct mr_list_elt *ref) {
175
176 struct mr_list_elt *elt = ref->prev;
177
178 if (elt != NULL) {
179 /* if there was a previous elt, delete it */
180 if (elt->prev != NULL) {
181 /* there is an elt before, shift it */
182 elt->prev->next = elt->next;
183 elt->next->prev = elt->prev;
184 mr_list_free_elt(elt);
185 } else {
186 /* that elt is the first one */
187 mr_list_del_elt_firt(list);
188 }
189 } else {
190 /* If not, ref is the first elt */
191 mr_msg(3, "No elt to delete available before the first one");
192 }
193}
Note: See TracBrowser for help on using the repository browser.