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

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

Fix a bug for allocation (pointer manipulation again - Thanks again Michel Loiseleur :-)

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