1 /*
2  * ilist.h
3  *
4  * Generic lists in C
5  *
6  * Author: MontaVista Software, Inc.
7  *         Corey Minyard <minyard@mvista.com>
8  *         source@mvista.com
9  *
10  * Copyright 2002,2003,2004,2005 MontaVista Software Inc.
11  *
12  * This software is available to you under a choice of one of two
13  * licenses.  You may choose to be licensed under the terms of the GNU
14  * Lesser General Public License (GPL) Version 2 or the modified BSD
15  * license below.  The following disclamer applies to both licenses:
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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
26  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * GNU Lesser General Public Licence
29  *
30  *  This program is free software; you can redistribute it and/or
31  *  modify it under the terms of the GNU Lesser General Public License
32  *  as published by the Free Software Foundation; either version 2 of
33  *  the License, or (at your option) any later version.
34  *
35  *  You should have received a copy of the GNU Lesser General Public
36  *  License along with this program; if not, write to the Free
37  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38  *
39  * Modified BSD Licence
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  *
45  *   1. Redistributions of source code must retain the above copyright
46  *      notice, this list of conditions and the following disclaimer.
47  *   2. Redistributions in binary form must reproduce the above
48  *      copyright notice, this list of conditions and the following
49  *      disclaimer in the documentation and/or other materials provided
50  *      with the distribution.
51  *   3. The name of the author may not be used to endorse or promote
52  *      products derived from this software without specific prior
53  *      written permission.
54  */
55 
56 #ifndef OPENIPMI_ILIST_H
57 #define OPENIPMI_ILIST_H
58 
59 typedef struct ilist_s ilist_t;
60 typedef struct ilist_iter_s ilist_iter_t;
61 
62 /* This is only so the user can supply their own data chunks for the
63    list entries.  This is ugly, but it allows the user to pre-allocate
64    (or allocate as part of the entry) the data for the list chunks,
65    and avoid having to worry about error returns from the list
66    operations. */
67 typedef struct ilist_item_s ilist_item_t;
68 
69 /* Returns NULL on failure. */
70 ilist_t *alloc_ilist(void);
71 ilist_iter_t *alloc_ilist_iter(ilist_t *list);
72 void free_ilist(ilist_t *list);
73 void free_ilist_iter(ilist_iter_t *iter);
74 
75 /* Returns true if the list is empty, false if not. */
76 int ilist_empty(ilist_t *list);
77 
78 /* Return false on failure, true on success.  entry may be NULL,
79    meaning you want the ilist code to supply the entry.  If you supply
80    an entry, the "malloced" flag will be set to zero for you. */
81 int ilist_add_head(ilist_t *list, void *item, ilist_item_t *entry);
82 int ilist_add_tail(ilist_t *list, void *item, ilist_item_t *entry);
83 int ilist_add_before(ilist_iter_t *iter, void *item, ilist_item_t *entry);
84 int ilist_add_after(ilist_iter_t *iter, void *item, ilist_item_t *entry);
85 
86 /* Return false on failure, true on success.  This will return a
87    failure (false) if you try to position past the end of the array or
88    try to set first or last on an empty array.  In that case it will
89    leave the iterator unchanged. */
90 int ilist_first(ilist_iter_t *iter);
91 int ilist_last(ilist_iter_t *iter);
92 int ilist_next(ilist_iter_t *iter);
93 int ilist_prev(ilist_iter_t *iter);
94 
95 /* Remove the first or last item from the list.  It will be deleted
96    from the list and returned.  If the list is empty, NULL will be
97    returned. */
98 void *ilist_remove_first(ilist_t *list);
99 void *ilist_remove_last(ilist_t *list);
100 
101 /* Remove a given item from the list, if it is there.  Return 1 if it
102    was found and 0 if it was not found. */
103 int ilist_remove_item_from_list(ilist_t *list, void *item);
104 
105 /* Returns failue (false) if unpositioned. */
106 int ilist_delete(ilist_iter_t *iter); /* Position on next element after del */
107 
108 /* Set unpositioned.  Next will go to the first item, prev to the last
109    item. */
110 void ilist_unpositioned(ilist_iter_t *iter);
111 
112 /* Returns NULL if unpositioned or list empty. */
113 void *ilist_get(ilist_iter_t *iter);
114 
115 /* This should return true if the item matches, false if not. */
116 typedef int (*ilist_search_cb)(void *item, void *cb_data);
117 
118 /* Search forward (starting at the next item) for something.  Returns
119    NULL if not found, the item if found.  iter will be positioned on
120    the item, too.  To search from the beginning, set the iterator to
121    the "unpositioined" position. */
122 void *ilist_search_iter(ilist_iter_t *iter, ilist_search_cb cmp, void *cb_data);
123 
124 /* Search from the beginning, but without an iterator.  This will return
125    the first item found. */
126 void *ilist_search(ilist_t *list, ilist_search_cb cmp, void *cb_data);
127 
128 /* Called with an iterator positioned on the item. */
129 typedef void (*ilist_iter_cb)(ilist_iter_t *iter, void *item, void *cb_data);
130 
131 /* Call the given handler for each item in the list.  You may delete
132    the current item the iterator references while this is happening,
133    but no other items. */
134 void ilist_iter(ilist_t *list, ilist_iter_cb handler, void *cb_data);
135 
136 /* Call the given handler for each item in the list, but run the list
137    backwards.  You may delete the current item the iterator references
138    while this is happening, but no other items. */
139 void ilist_iter_rev(ilist_t *list, ilist_iter_cb handler, void *cb_data);
140 
141 /* Initialize a statically declared iterator. */
142 void ilist_init_iter(ilist_iter_t *iter, ilist_t *list);
143 
144 /* Return -1 if item1 < item2, 0 if item1 == item2, and 1 if item1 > item2 */
145 typedef int (*ilist_sort_cb)(void *item1, void *item2);
146 
147 void ilist_sort(ilist_t *list, ilist_sort_cb cmp);
148 
149 /* A two-item list.  This is useful for managing list of handlers
150    where you have a callback handler and a data item.  You create it
151    with the given two data items, and when you call
152    ilist_iter_twoitem, it will call the handler you pass in with the
153    two data items you have given. */
154 
155 typedef void (*ilist_twoitem_cb)(void *data, void *cb_data1, void *cb_data2);
156 
157 /* Add an entry to the list.  Returns 0 upon failure, 1 if successful.
158    Duplicates are allowed. */
159 int ilist_add_twoitem(ilist_t *list, void *cb_data1, void *cb_data2);
160 
161 /* Remove an entry, returns 1 if present, 0 if not. */
162 int ilist_remove_twoitem(ilist_t *list, void *cb_data1, void *cb_data2);
163 
164 /* Returns 1 if the entry exists in the list, 0 if not. */
165 int ilist_twoitem_exists(ilist_t *list, void *cb_data1, void *cb_data2);
166 
167 /* Call all the callbacks in the list */
168 void ilist_iter_twoitem(ilist_t *ilist, ilist_twoitem_cb handler, void *data);
169 
170 void ilist_twoitem_destroy(ilist_t *list);
171 
172 /* Internal data structures, DO NOT USE THESE. */
173 
174 struct ilist_item_s
175 {
176     int malloced;
177     ilist_item_t *next, *prev;
178     void *item;
179 };
180 
181 struct ilist_s
182 {
183     ilist_item_t *head;
184 };
185 
186 struct ilist_iter_s
187 {
188     ilist_t      *list;
189     ilist_item_t *curr;
190 };
191 
192 /* You must define these. */
193 void *ilist_mem_alloc(size_t size);
194 void ilist_mem_free(void *data);
195 
196 #endif /* OPENIPMI_ILIST_H */
197