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

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

Addition of a double chained list (Idea from M. Loiseleur) to support tapecatalog and probably other data types later

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