57837128736bfeb96d84968b851bfae97bca1c41
1 /*
2 * @file List.c
3 *
4 * @brief Creates a doubly linked list.
5 *
6 *
7 * @ver 02.00.00.53_alpha2
8 *
9 * ============================================================================
10 *
11 * Copyright (c) 2010, Texas Instruments Incorporated
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * * Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * * Neither the name of Texas Instruments Incorporated nor the names of
25 * its contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
30 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
32 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
35 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
37 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
38 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * Contact information for paper mail:
40 * Texas Instruments
41 * Post Office Box 655303
42 * Dallas, Texas 75265
43 * Contact information:
44 * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
45 * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
46 * ============================================================================
47 *
48 */
51 #include "proto.h"
52 #include "List.h"
54 /* =============================================================================
55 * All success and failure codes for the module. Defined here because they are
56 * only used internally.
57 * =============================================================================
58 */
60 /*!
61 * @def List_S_BUSY
62 * @brief The resource is still in use
63 */
64 #define List_S_BUSY 2
66 /*!
67 * @def List_S_ALREADYSETUP
68 * @brief The module has been already setup
69 */
70 #define List_S_ALREADYSETUP 1
72 /*!
73 * @def List_S_SUCCESS
74 * @brief Operation is successful.
75 */
76 #define List_S_SUCCESS 0
78 /*!
79 * @def List_E_FAIL
80 * @brief Generic failure.
81 */
82 #define List_E_FAIL -1
84 /*!
85 * @def List_E_INVALIDARG
86 * @brief Argument passed to function is invalid.
87 */
88 #define List_E_INVALIDARG -2
90 /*!
91 * @def List_E_MEMORY
92 * @brief Operation resulted in memory failure.
93 */
94 #define List_E_MEMORY -3
96 /*!
97 * @def List_E_ALREADYEXISTS
98 * @brief The specified entity already exists.
99 */
100 #define List_E_ALREADYEXISTS -4
102 /*!
103 * @def List_E_NOTFOUND
104 * @brief Unable to find the specified entity.
105 */
106 #define List_E_NOTFOUND -5
108 /*!
109 * @def List_E_TIMEOUT
110 * @brief Operation timed out.
111 */
112 #define List_E_TIMEOUT -6
114 /*!
115 * @def List_E_INVALIDSTATE
116 * @brief Module is not initialized.
117 */
118 #define List_E_INVALIDSTATE -7
120 /*!
121 * @def List_E_OSFAILURE
122 * @brief A failure occurred in an OS-specific call
123 */
124 #define List_E_OSFAILURE -8
126 /*!
127 * @def List_E_RESOURCE
128 * @brief Specified resource is not available
129 */
130 #define List_E_RESOURCE -9
132 /*!
133 * @def List_E_RESTART
134 * @brief Operation was interrupted. Please restart the operation
135 */
136 #define List_E_RESTART -10
138 /* Function to remove specific elem from list */
139 void
140 List_elemClear (List_Elem * elem)
141 {
142 if (elem != NULL) {
143 elem->next = elem->prev = elem;
144 }
145 }
148 /* Function to check if list is empty */
149 bool
150 List_empty (List_Handle handle)
151 {
152 bool isEmpty = false;
153 List_Elem * obj = (List_Elem *) handle;
154 List_Elem *elem = NULL;
156 if (handle != NULL) {
157 elem = obj->next;
158 if ((elem == obj) && (elem == obj->prev)) {
159 /*! @retval TRUE List is empty */
160 isEmpty = true;
161 }
162 }
164 /*! @retval FALSE List is not empty */
165 return isEmpty;
166 }
169 /* Function to get front element */
170 List_Elem *
171 List_get (List_Handle handle)
172 {
173 List_Elem * elem = NULL;
175 if (handle != NULL) {
176 elem = List_dequeue(handle);
177 }
179 /*! @retval Valid-pointer Pointer to first element */
180 return elem ;
181 }
184 /* Function to put elem at the end */
185 void
186 List_put (List_Handle handle, List_Elem * elem)
187 {
188 if (handle != NULL && elem != NULL) {
189 List_enqueue (handle, elem);
190 }
191 }
195 /* Function to get next elem of current one (non-atomic) */
196 List_Elem *
197 List_next (List_Handle handle, List_Elem * elem)
198 {
199 List_Elem * retElem = NULL;
200 List_Elem * obj = (List_Elem *) handle;
202 if (handle != NULL) {
203 /* elem == NULL -> start at the head */
204 if (elem == NULL) {
205 retElem = obj->next;
206 }
207 else {
208 retElem = elem->next;
209 }
211 if (retElem == (List_Elem *) obj) {
212 /*! @retval NULL List reached end or list is empty */
213 retElem = NULL;
214 }
216 }
218 /*! @retval Valid-pointer Pointer to the next element */
219 return retElem;
220 }
223 /* Function to get previous elem of current one (non-atomic) */
224 List_Elem *
225 List_prev (List_Handle handle, List_Elem * elem)
226 {
227 List_Elem * retElem = NULL;
228 List_Elem * obj = (List_Elem *) handle;
230 if (handle != NULL && elem != NULL) {
231 /* elem == NULL -> start at the head */
232 if (elem == NULL) {
233 retElem = obj->prev;
234 }
235 else {
236 retElem = elem->prev;
237 }
239 if (retElem == (List_Elem *)obj) {
240 /*! @retval NULL List reached end or list is empty */
241 retElem = NULL;
242 }
243 }
245 /*! @retval Valid-pointer Pointer to the prev element */
246 return retElem;
247 }
250 /* Function to insert elem before existing elem */
251 void
252 List_insert (List_Handle handle, List_Elem * newElem, List_Elem * curElem)
253 {
254 if (handle != NULL && newElem != NULL && curElem != NULL) {
255 /* Cannot directly call enqueue since the object has other fields */
256 newElem->next = curElem;
257 newElem->prev = curElem->prev;
258 newElem->prev->next = newElem;
259 curElem->prev = newElem;
260 }
261 }
264 /* Function to remove specific elem from list */
265 void
266 List_remove (List_Handle handle, List_Elem * elem)
267 {
268 if (elem != NULL) {
269 elem->prev->next = elem->next;
270 elem->next->prev = elem->prev;
271 }
272 }
275 /* Function to put element before head */
276 void
277 List_putHead (List_Handle handle, List_Elem *elem)
278 {
279 if (handle != NULL && elem != NULL) {
280 List_enqueueHead (handle, elem);
281 }
282 }
285 /* Get element from front of List (non-atomic) */
286 List_Elem *
287 List_dequeue (List_Handle handle)
288 {
289 List_Elem * elem = NULL;
290 List_Elem * obj = (List_Elem *) handle;
292 elem = obj->next;
293 /* See if the List was empty */
294 if (elem == (List_Elem *)obj) {
295 /*! @retval NULL List is empty */
296 elem = NULL;
297 }
298 else {
299 obj->next = elem->next;
300 elem->next->prev = obj;
301 }
302 return elem;
303 }
306 /* Put element at end of List (non-atomic) */
307 void
308 List_enqueue (List_Handle handle, List_Elem * elem)
309 {
310 List_Elem * obj = (List_Elem *) handle;
312 if (handle != NULL && elem != NULL) {
313 elem->next = obj;
314 elem->prev = obj->prev;
315 obj->prev->next = elem;
316 obj->prev = elem;
317 }
318 }
321 /* Put element at head of List (non-atomic) */
322 void
323 List_enqueueHead (List_Handle handle, List_Elem * elem)
324 {
325 List_Elem * obj = (List_Elem *) handle;
327 if (handle != NULL && elem != NULL) {
328 elem->next = obj->next;
329 elem->prev = obj;
330 obj->next->prev = elem;
331 obj->next = elem;
332 }
333 }
336 /* Move list element to new place in list (non-atomic) */
337 void
338 List_move(List_Handle handle, List_Elem *list)
339 {
340 List_remove(handle, list);
341 List_enqueueHead(handle, list);
342 }
345 /* Check if the list has only one element (non-atomic) */
346 int
347 List_is_singular(List_Handle handle)
348 {
349 List_Elem *elem = (List_Elem *)handle;
350 return !List_empty(handle) && (elem->next == elem->prev);
351 }