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, 13 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.