1 /**
2 * \file
3 *
4 * \brief List functionality implementation.
5 *
6 * Copyright (C) 2014 Atmel Corporation. All rights reserved.
7 *
8 * \asf_license_start
9 *
10 * \page License
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 *
22 * 3. The name of Atmel may not be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * 4. This software may only be redistributed and used in connection with an
26 * Atmel microcontroller product.
27 *
28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 *
40 * \asf_license_stop
41 *
42 */
43
44 #include <utils_list.h>
45 #include <utils_assert.h>
46
47 /**
48 * \brief Check whether element belongs to list
49 */
is_list_element(const struct list_descriptor * const list,const void * const element)50 bool is_list_element(const struct list_descriptor *const list, const void *const element)
51 {
52 struct list_element *it;
53 for (it = list->head; it; it = it->next) {
54 if (it == element) {
55 return true;
56 }
57 }
58
59 return false;
60 }
61
62 /**
63 * \brief Insert an element as list head
64 */
list_insert_as_head(struct list_descriptor * const list,void * const element)65 void list_insert_as_head(struct list_descriptor *const list, void *const element)
66 {
67 ASSERT(!is_list_element(list, element));
68
69 ((struct list_element *)element)->next = list->head;
70 list->head = (struct list_element *)element;
71 }
72
73 /**
74 * \brief Insert an element after the given list element
75 */
list_insert_after(void * const after,void * const element)76 void list_insert_after(void *const after, void *const element)
77 {
78 ((struct list_element *)element)->next = ((struct list_element *)after)->next;
79 ((struct list_element *)after)->next = (struct list_element *)element;
80 }
81
82 /**
83 * \brief Insert an element at list end
84 */
list_insert_at_end(struct list_descriptor * const list,void * const element)85 void list_insert_at_end(struct list_descriptor *const list, void *const element)
86 {
87 struct list_element *it = list->head;
88
89 ASSERT(!is_list_element(list, element));
90
91 if (!list->head) {
92 list->head = (struct list_element *)element;
93 ((struct list_element *)element)->next = NULL;
94 return;
95 }
96
97 while (it->next) {
98 it = it->next;
99 }
100 it->next = (struct list_element *)element;
101 ((struct list_element *)element)->next = NULL;
102 }
103
104 /**
105 * \brief Removes list head
106 */
list_remove_head(struct list_descriptor * const list)107 void *list_remove_head(struct list_descriptor *const list)
108 {
109 if (list->head) {
110 struct list_element *tmp = list->head;
111
112 list->head = list->head->next;
113 return (void *)tmp;
114 }
115
116 return NULL;
117 }
118
119 /**
120 * \brief Removes list element
121 */
list_delete_element(struct list_descriptor * const list,const void * const element)122 bool list_delete_element(struct list_descriptor *const list, const void *const element)
123 {
124 if (!element) {
125 return false;
126 }
127
128 if (list->head == element) {
129 list->head = list->head->next;
130 return true;
131 } else {
132 struct list_element *it = list->head;
133
134 while (it && it->next != element) {
135 it = it->next;
136 }
137 if (it) {
138 it->next = ((struct list_element *)element)->next;
139 return true;
140 }
141 }
142
143 return false;
144 }
145
146 //@}
147