source: MondoRescue/branches/3.2/mondo/src/lib/mr_list.c@ 3510

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

Typos

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