fix various warnings reported by cparser
[libfirm] / ir / adt / plist.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief Simple, non circular, double linked pointer list.
23  * @note  Created because the properties of the standard circular list were not
24  *        very well suited for the interference graph implementation.
25  *        This list uses an obstack and a free-list to efficiently manage its
26  *        elements.
27  * @author  Kimon Hoffmann
28  * @date    14.07.2005
29  * @version $Id$
30  */
31 #include <stdlib.h>
32
33 #include "plist.h"
34
35 /**
36  * Helper macro that returns a new uninitialized list element by either
37  * fetching one from the free-list or allocating a new one on the lists
38  * obstack.
39  * @param list the list for which to allocate the element.
40  * @return the newly allocated, uninitialized element.
41  */
42 static plist_element_t *allocate_element(plist_t* list)
43 {
44         plist_element_t *new_element;
45
46         if (list->first_free_element != NULL) {
47                 new_element              = list->first_free_element;
48                 list->first_free_element = new_element->next;
49                 new_element->next        = NULL;
50         }
51         else {
52                 new_element = OALLOC(list->obst, plist_element_t);
53         }
54
55         return new_element;
56 }
57
58 plist_t *plist_new(void)
59 {
60         plist_t *list = xmalloc(sizeof(*list) + sizeof(*list->obst));
61
62         list->obst               = (struct obstack *)&list[1];
63         list->foreign_obstack    = 0;
64         list->first_element      = NULL;
65         list->last_element       = NULL;
66         list->first_free_element = NULL;
67         list->element_count      = 0;
68
69         obstack_init(list->obst);
70         return list;
71 }
72
73 plist_t *plist_obstack_new(struct obstack *obst)
74 {
75         plist_t *list = OALLOC(obst, plist_t);
76
77         list->obst               = obst;
78         list->foreign_obstack    = 1;
79         list->first_element      = NULL;
80         list->last_element       = NULL;
81         list->first_free_element = NULL;
82         list->element_count      = 0;
83
84         return list;
85 }
86
87 void plist_free(plist_t *list)
88 {
89         list->first_element      = NULL;
90         list->last_element       = NULL;
91         list->first_free_element = NULL;
92         list->element_count      = 0;
93
94         if (! list->foreign_obstack) {
95                 obstack_free(list->obst, NULL);
96                 xfree(list);
97         }
98 }
99
100 void plist_insert_back(plist_t *list, void *value)
101 {
102         if (list->last_element != NULL) {
103                 plist_insert_after(list, list->last_element, value);
104         }
105         else {
106                 plist_element_t *newElement = allocate_element(list);
107
108                 newElement->data    = value;
109                 newElement->prev    = NULL;
110                 newElement->next    = NULL;
111                 list->first_element = list->last_element = newElement;
112                 list->element_count = 1;
113         }
114 }
115
116 void plist_insert_front(plist_t *list, void *value)
117 {
118         if (list->first_element != NULL) {
119                 plist_insert_before(list, list->first_element, value);
120         }
121         else {
122                 plist_element_t *newElement = allocate_element(list);
123
124                 newElement->data    = value;
125                 newElement->prev    = NULL;
126                 newElement->next    = NULL;
127                 list->first_element = list->last_element = newElement;
128                 list->element_count = 1;
129         }
130 }
131
132 void plist_insert_before(plist_t *list, plist_element_t *element, void *value)
133 {
134         plist_element_t *prevElement;
135         plist_element_t *newElement = allocate_element(list);
136
137         newElement->data = value;
138         newElement->next = element;
139         prevElement      = element->prev;
140         newElement->prev = prevElement;
141
142         if (prevElement != NULL) {
143                 prevElement->next = newElement;
144         }
145         else {
146                 list->first_element = newElement;
147         }
148
149         element->prev = newElement;
150         ++list->element_count;
151 }
152
153 void plist_insert_after(plist_t* list, plist_element_t* element, void* value)
154 {
155         plist_element_t *nextElement;
156         plist_element_t *newElement = allocate_element(list);
157
158         newElement->data = value;
159         newElement->prev = element;
160         nextElement      = element->next;
161         newElement->next = nextElement;
162
163         if (nextElement != NULL) {
164                 nextElement->prev = newElement;
165         }
166         else {
167                 list->last_element = newElement;
168         }
169
170         element->next = newElement;
171         ++list->element_count;
172 }
173
174 int plist_has_value(plist_t *list, void *value)
175 {
176         plist_element_t *iter;
177
178         for (iter = plist_first(list); iter; iter = plist_element_get_next(iter)) {
179                 if (plist_element_get_value(iter) == value)
180                         return 1;
181         }
182
183         return 0;
184 }
185
186 plist_element_t *plist_find_value(plist_t *list, void *value)
187 {
188         plist_element_t *iter;
189
190         for (iter = plist_first(list); iter; iter = plist_element_get_next(iter)) {
191                 if (plist_element_get_value(iter) == value)
192                         return iter;
193         }
194
195         return NULL;
196 }
197
198 void plist_erase(plist_t *list, plist_element_t *element)
199 {
200         plist_element_t *next_element = element->next;
201         plist_element_t *prev_element = element->prev;
202
203         if (next_element != NULL) {
204                 next_element->prev = prev_element;
205         }
206         else {
207                 list->last_element = prev_element;
208         }
209
210         if (prev_element != NULL) {
211                 prev_element->next = next_element;
212         }
213         else {
214                 list->first_element = next_element;
215         }
216
217         --list->element_count;
218
219         /* Clean the element and prepend it to the free list */
220         element->prev            = NULL; /* The allocation code expects prev to be NULL */
221         element->next            = list->first_free_element;
222         list->first_free_element = element;
223 }
224
225 void plist_clear(plist_t *list)
226 {
227         plist_element_t *curr_element = list->first_element;
228
229         while (curr_element != NULL) {
230                 curr_element->prev = NULL;
231                 curr_element       = curr_element->next;
232         }
233
234         curr_element = list->last_element;
235
236         if (curr_element != NULL) {
237                 curr_element->next = list->first_free_element;
238         }
239
240         list->first_free_element = list->first_element;
241         list->first_element      = 0;
242         list->last_element       = 0;
243         list->element_count      = 0;
244 }