1 /*
2  * Copyright (c) 2012, The Linux Foundation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  * *    * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above
10  *       copyright notice, this list of conditions and the following
11  *       disclaimer in the documentation and/or other materials provided
12  *       with the distribution.
13  *     * Neither the name of The Linux Foundation nor the names of its
14  *       contributors may be used to endorse or promote products derived
15  *       from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "list.h"
35 #include <utils/Log.h>
36 
init_list_head(struct list_node * head)37 int init_list_head(struct list_node *head)
38 {
39     if (head == NULL)
40         return -1;
41 
42     memset(head, 0, sizeof(*head));
43 
44     return 0;
45 }
46 
add_list_node(struct list_node * head,void * data)47 struct list_node *add_list_node(struct list_node *head, void *data)
48 {
49     /* Create a new list_node. And put 'data' into it. */
50     struct list_node *new_node;
51 
52     if (head == NULL) {
53         return NULL;
54     }
55 
56     if (!(new_node = malloc(sizeof(struct list_node)))) {
57         return NULL;
58     }
59 
60     new_node->data = data;
61     new_node->next = head->next;
62     new_node->compare = head->compare;
63     new_node->dump = head->dump;
64     head->next = new_node;
65 
66     return new_node;
67 }
68 
is_list_empty(struct list_node * head)69 int is_list_empty(struct list_node *head)
70 {
71     return (head == NULL || head->next == NULL);
72 }
73 
74 /*
75  * Delink and de-allocate 'node'.
76  */
remove_list_node(struct list_node * head,struct list_node * del_node)77 int remove_list_node(struct list_node *head, struct list_node *del_node)
78 {
79     struct list_node *current_node;
80     struct list_node *saved_node;
81 
82     if (head == NULL || head->next == NULL) {
83         return -1;
84     }
85 
86     current_node = head->next;
87     saved_node = head;
88 
89     while (current_node && current_node != del_node) {
90         saved_node = current_node;
91         current_node = current_node->next;
92     }
93 
94     if (saved_node) {
95         if (current_node) {
96             saved_node->next = current_node->next;
97         } else {
98             /* Node not found. */
99             return -1;
100         }
101     }
102 
103     if (del_node) {
104         free(del_node);
105     }
106 
107     return 0;
108 }
109 
dump_list(struct list_node * head)110 void dump_list(struct list_node *head)
111 {
112     struct list_node *current_node = head;
113 
114     if (head == NULL)
115         return;
116 
117     printf("List:\n");
118 
119     while ((current_node = current_node->next)) {
120         if (current_node->dump) {
121             current_node->dump(current_node->data);
122         }
123     }
124 }
125 
find_node(struct list_node * head,void * comparison_data)126 struct list_node *find_node(struct list_node *head, void *comparison_data)
127 {
128     struct list_node *current_node = head;
129 
130     if (head == NULL)
131         return NULL;
132 
133     while ((current_node = current_node->next)) {
134         if (current_node->compare) {
135             if (current_node->compare(current_node->data,
136                     comparison_data) == 0) {
137                 /* Match found. Return current_node. */
138                 return current_node;
139             }
140         }
141     }
142 
143     /* No match found. */
144     return NULL;
145 }
146