Contiki-Inga 3.x
list.c
Go to the documentation of this file.
1 /**
2  * \addtogroup list
3  * @{
4  */
5 
6 /**
7  * \file
8  * Linked list library implementation.
9  *
10  * \author Adam Dunkels <adam@sics.se>
11  *
12  */
13 
14 /*
15  * Copyright (c) 2004, Swedish Institute of Computer Science.
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21  * 1. Redistributions of source code must retain the above copyright
22  * notice, this list of conditions and the following disclaimer.
23  * 2. Redistributions in binary form must reproduce the above copyright
24  * notice, this list of conditions and the following disclaimer in the
25  * documentation and/or other materials provided with the distribution.
26  * 3. Neither the name of the Institute nor the names of its contributors
27  * may be used to endorse or promote products derived from this software
28  * without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
31  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
34  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40  * SUCH DAMAGE.
41  *
42  * This file is part of the Contiki operating system.
43  *
44  * Author: Adam Dunkels <adam@sics.se>
45  *
46  */
47 #include "lib/list.h"
48 
49 #define NULL 0
50 
51 struct list {
52  struct list *next;
53 };
54 
55 /*---------------------------------------------------------------------------*/
56 /**
57  * Initialize a list.
58  *
59  * This function initalizes a list. The list will be empty after this
60  * function has been called.
61  *
62  * \param list The list to be initialized.
63  */
64 void
66 {
67  *list = NULL;
68 }
69 /*---------------------------------------------------------------------------*/
70 /**
71  * Get a pointer to the first element of a list.
72  *
73  * This function returns a pointer to the first element of the
74  * list. The element will \b not be removed from the list.
75  *
76  * \param list The list.
77  * \return A pointer to the first element on the list.
78  *
79  * \sa list_tail()
80  */
81 void *
83 {
84  return *list;
85 }
86 /*---------------------------------------------------------------------------*/
87 /**
88  * Duplicate a list.
89  *
90  * This function duplicates a list by copying the list reference, but
91  * not the elements.
92  *
93  * \note This function does \b not copy the elements of the list, but
94  * merely duplicates the pointer to the first element of the list.
95  *
96  * \param dest The destination list.
97  * \param src The source list.
98  */
99 void
101 {
102  *dest = *src;
103 }
104 /*---------------------------------------------------------------------------*/
105 /**
106  * Get the tail of a list.
107  *
108  * This function returns a pointer to the elements following the first
109  * element of a list. No elements are removed by this function.
110  *
111  * \param list The list
112  * \return A pointer to the element after the first element on the list.
113  *
114  * \sa list_head()
115  */
116 void *
118 {
119  struct list *l;
120 
121  if(*list == NULL) {
122  return NULL;
123  }
124 
125  for(l = *list; l->next != NULL; l = l->next);
126 
127  return l;
128 }
129 /*---------------------------------------------------------------------------*/
130 /**
131  * Add an item at the end of a list.
132  *
133  * This function adds an item to the end of the list.
134  *
135  * \param list The list.
136  * \param item A pointer to the item to be added.
137  *
138  * \sa list_push()
139  *
140  */
141 void
142 list_add(list_t list, void *item)
143 {
144  struct list *l;
145 
146  /* Make sure not to add the same element twice */
147  list_remove(list, item);
148 
149  ((struct list *)item)->next = NULL;
150 
151  l = list_tail(list);
152 
153  if(l == NULL) {
154  *list = item;
155  } else {
156  l->next = item;
157  }
158 }
159 /*---------------------------------------------------------------------------*/
160 /**
161  * Add an item to the start of the list.
162  */
163 void
164 list_push(list_t list, void *item)
165 {
166  /* struct list *l;*/
167 
168  /* Make sure not to add the same element twice */
169  list_remove(list, item);
170 
171  ((struct list *)item)->next = *list;
172  *list = item;
173 }
174 /*---------------------------------------------------------------------------*/
175 /**
176  * Remove the last object on the list.
177  *
178  * This function removes the last object on the list and returns it.
179  *
180  * \param list The list
181  * \return The removed object
182  *
183  */
184 void *
186 {
187  struct list *l, *r;
188 
189  if(*list == NULL) {
190  return NULL;
191  }
192  if(((struct list *)*list)->next == NULL) {
193  l = *list;
194  *list = NULL;
195  return l;
196  }
197 
198  for(l = *list; l->next->next != NULL; l = l->next);
199 
200  r = l->next;
201  l->next = NULL;
202 
203  return r;
204 }
205 /*---------------------------------------------------------------------------*/
206 /**
207  * Remove the first object on a list.
208  *
209  * This function removes the first object on the list and returns a
210  * pointer to it.
211  *
212  * \param list The list.
213  * \return Pointer to the removed element of list.
214  */
215 /*---------------------------------------------------------------------------*/
216 void *
218 {
219  struct list *l;
220  l = *list;
221  if(*list != NULL) {
222  *list = ((struct list *)*list)->next;
223  }
224 
225  return l;
226 }
227 /*---------------------------------------------------------------------------*/
228 /**
229  * Remove a specific element from a list.
230  *
231  * This function removes a specified element from the list.
232  *
233  * \param list The list.
234  * \param item The item that is to be removed from the list.
235  *
236  */
237 /*---------------------------------------------------------------------------*/
238 void
239 list_remove(list_t list, void *item)
240 {
241  struct list *l, *r;
242 
243  if(*list == NULL) {
244  return;
245  }
246 
247  r = NULL;
248  for(l = *list; l != NULL; l = l->next) {
249  if(l == item) {
250  if(r == NULL) {
251  /* First on list */
252  *list = l->next;
253  } else {
254  /* Not first on list */
255  r->next = l->next;
256  }
257  l->next = NULL;
258  return;
259  }
260  r = l;
261  }
262 }
263 /*---------------------------------------------------------------------------*/
264 /**
265  * Get the length of a list.
266  *
267  * This function counts the number of elements on a specified list.
268  *
269  * \param list The list.
270  * \return The length of the list.
271  */
272 /*---------------------------------------------------------------------------*/
273 int
275 {
276  struct list *l;
277  int n = 0;
278 
279  for(l = *list; l != NULL; l = l->next) {
280  ++n;
281  }
282 
283  return n;
284 }
285 /*---------------------------------------------------------------------------*/
286 /**
287  * \brief Insert an item after a specified item on the list
288  * \param list The list
289  * \param previtem The item after which the new item should be inserted
290  * \param newitem The new item that is to be inserted
291  * \author Adam Dunkels
292  *
293  * This function inserts an item right after a specified
294  * item on the list. This function is useful when using
295  * the list module to ordered lists.
296  *
297  * If previtem is NULL, the new item is placed at the
298  * start of the list.
299  *
300  */
301 void
302 list_insert(list_t list, void *previtem, void *newitem)
303 {
304  if(previtem == NULL) {
305  list_push(list, newitem);
306  } else {
307 
308  ((struct list *)newitem)->next = ((struct list *)previtem)->next;
309  ((struct list *)previtem)->next = newitem;
310  }
311 }
312 /*---------------------------------------------------------------------------*/
313 /**
314  * \brief Get the next item following this item
315  * \param item A list item
316  * \returns A next item on the list
317  *
318  * This function takes a list item and returns the next
319  * item on the list, or NULL if there are no more items on
320  * the list. This function is used when iterating through
321  * lists.
322  */
323 void *
324 list_item_next(void *item)
325 {
326  return item == NULL? NULL: ((struct list *)item)->next;
327 }
328 /*---------------------------------------------------------------------------*/
329 /** @} */