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