1*2264Sjacobs /*
2*2264Sjacobs * CDDL HEADER START
3*2264Sjacobs *
4*2264Sjacobs * The contents of this file are subject to the terms of the
5*2264Sjacobs * Common Development and Distribution License (the "License").
6*2264Sjacobs * You may not use this file except in compliance with the License.
7*2264Sjacobs *
8*2264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2264Sjacobs * or http://www.opensolaris.org/os/licensing.
10*2264Sjacobs * See the License for the specific language governing permissions
11*2264Sjacobs * and limitations under the License.
12*2264Sjacobs *
13*2264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each
14*2264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2264Sjacobs * If applicable, add the following below this CDDL HEADER, with the
16*2264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying
17*2264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner]
18*2264Sjacobs *
19*2264Sjacobs * CDDL HEADER END
20*2264Sjacobs */
21*2264Sjacobs /*
22*2264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23*2264Sjacobs * Use is subject to license terms.
24*2264Sjacobs */
25*2264Sjacobs
26*2264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI"
27*2264Sjacobs
28*2264Sjacobs /*LINTLIBRARY*/
29*2264Sjacobs
30*2264Sjacobs #include <stdio.h>
31*2264Sjacobs #include <stdlib.h>
32*2264Sjacobs #include <unistd.h>
33*2264Sjacobs #include <sys/types.h>
34*2264Sjacobs #include <stdarg.h>
35*2264Sjacobs #include <syslog.h>
36*2264Sjacobs #include <stdlib.h>
37*2264Sjacobs #include <strings.h>
38*2264Sjacobs
39*2264Sjacobs #include <list.h>
40*2264Sjacobs
41*2264Sjacobs
42*2264Sjacobs static int _list_increment = 64; /* just so It can be tuned with adb(1) */
43*2264Sjacobs /*
44*2264Sjacobs * list_append() takes in a list (type **) and a pointer to an item to add
45*2264Sjacobs * to the list and returns a new list with the new item appended on the
46*2264Sjacobs * end. The list is NULL terminated. If there was an error, NULL is
47*2264Sjacobs * returned. For reasonable efficiency, the list will be allocated
48*2264Sjacobs * in blocks of size _list_increment.
49*2264Sjacobs */
50*2264Sjacobs void **
list_append(void ** list,void * item)51*2264Sjacobs list_append(void **list, void *item)
52*2264Sjacobs {
53*2264Sjacobs #ifdef DEBUG
54*2264Sjacobs syslog(LOG_DEBUG, "list_append(0x%x, 0x%x)", list, item);
55*2264Sjacobs #endif
56*2264Sjacobs if (item == NULL)
57*2264Sjacobs return (list);
58*2264Sjacobs
59*2264Sjacobs if (list == NULL) {
60*2264Sjacobs list = (void **)calloc(_list_increment, sizeof (void *));
61*2264Sjacobs (void) memset(list, NULL, (_list_increment * sizeof (void *)));
62*2264Sjacobs list[0] = item;
63*2264Sjacobs } else {
64*2264Sjacobs int count;
65*2264Sjacobs
66*2264Sjacobs for (count = 0; list[count] != NULL; count++);
67*2264Sjacobs
68*2264Sjacobs if ((count + 1) % _list_increment == 0) { /* increase size */
69*2264Sjacobs void **new_list = NULL;
70*2264Sjacobs int new_size = (((count + 1) / _list_increment) + 1) *
71*2264Sjacobs _list_increment;
72*2264Sjacobs
73*2264Sjacobs new_list = (void **)calloc(new_size,
74*2264Sjacobs sizeof (void *));
75*2264Sjacobs (void) memset(new_list, NULL,
76*2264Sjacobs (new_size * sizeof (void *)));
77*2264Sjacobs for (count = 0; list[count] != NULL; count++)
78*2264Sjacobs new_list[count] = list[count];
79*2264Sjacobs free(list);
80*2264Sjacobs list = new_list;
81*2264Sjacobs }
82*2264Sjacobs list[count] = item;
83*2264Sjacobs }
84*2264Sjacobs return (list);
85*2264Sjacobs }
86*2264Sjacobs
87*2264Sjacobs
88*2264Sjacobs void **
list_append_unique(void ** list,void * item,int (* cmp)(void *,void *))89*2264Sjacobs list_append_unique(void **list, void *item, int (*cmp)(void *, void*))
90*2264Sjacobs {
91*2264Sjacobs if (list_locate(list, cmp, item))
92*2264Sjacobs return (list);
93*2264Sjacobs
94*2264Sjacobs list = list_append(list, item);
95*2264Sjacobs return (list);
96*2264Sjacobs }
97*2264Sjacobs
98*2264Sjacobs
99*2264Sjacobs /*
100*2264Sjacobs * list_locate() iterates through the list passed in and uses the comparison
101*2264Sjacobs * routine and element passed in to find an element in the list. It
102*2264Sjacobs * returns the first element matched, or NULL if none exists
103*2264Sjacobs */
104*2264Sjacobs void *
list_locate(void ** list,int (* compair)(void *,void *),void * element)105*2264Sjacobs list_locate(void **list, int (*compair)(void *, void *), void *element)
106*2264Sjacobs {
107*2264Sjacobs int current = 0;
108*2264Sjacobs
109*2264Sjacobs #ifdef DEBUG
110*2264Sjacobs syslog(LOG_DEBUG, "list_locate()");
111*2264Sjacobs #endif
112*2264Sjacobs if (list != NULL)
113*2264Sjacobs for (current = 0; list[current] != NULL; current++)
114*2264Sjacobs if ((compair)(list[current], element) == 0)
115*2264Sjacobs return (list[current]);
116*2264Sjacobs return (NULL);
117*2264Sjacobs }
118*2264Sjacobs
119*2264Sjacobs
120*2264Sjacobs /*
121*2264Sjacobs * list_concatenate() takes in two NULL terminated lists of items (type **)
122*2264Sjacobs * and creates a new list with items from list2 appended on the end of
123*2264Sjacobs * the list of items from list1. The result is a list (type **). If
124*2264Sjacobs * there is a failure, NULL is returned.
125*2264Sjacobs */
126*2264Sjacobs void **
list_concatenate(void ** list1,void ** list2)127*2264Sjacobs list_concatenate(void **list1, void **list2)
128*2264Sjacobs {
129*2264Sjacobs void **list = NULL;
130*2264Sjacobs int size1 = 0,
131*2264Sjacobs size2 = 0,
132*2264Sjacobs new_size = 0;
133*2264Sjacobs #ifdef DEBUG
134*2264Sjacobs syslog(LOG_DEBUG, "list_concatenate(0x%x, 0x%x)", list1, list2);
135*2264Sjacobs #endif
136*2264Sjacobs if ((list1 == NULL) || (list2 == NULL))
137*2264Sjacobs return ((list1 != NULL) ? list1 : list2);
138*2264Sjacobs
139*2264Sjacobs for (size1 = 0; list1[size1] != NULL; size1++);
140*2264Sjacobs for (size2 = 0; list2[size2] != NULL; size2++);
141*2264Sjacobs
142*2264Sjacobs /* list1 + list2 padded to a multiple of _list_increment */
143*2264Sjacobs new_size = ((size1 + size2)/_list_increment + 2) * _list_increment;
144*2264Sjacobs
145*2264Sjacobs if ((list = (void **)calloc((new_size), sizeof (void *)))
146*2264Sjacobs != NULL) {
147*2264Sjacobs int count = 0;
148*2264Sjacobs
149*2264Sjacobs (void) memset(list, NULL, (new_size * sizeof (void *)));
150*2264Sjacobs
151*2264Sjacobs for (size1 = 0; list1[size1] != NULL; size1++)
152*2264Sjacobs list[count++] = list1[size1];
153*2264Sjacobs for (size2 = 0; list2[size2] != NULL; size2++)
154*2264Sjacobs list[count++] = list2[size2];
155*2264Sjacobs free(list1);
156*2264Sjacobs }
157*2264Sjacobs return (list);
158*2264Sjacobs }
159*2264Sjacobs
160*2264Sjacobs
161*2264Sjacobs /*
162*2264Sjacobs * list_iterate() take in a list, pointer to a function, and variable number
163*2264Sjacobs * of arguements following. list_iterate() will iterate through the list
164*2264Sjacobs * calling the functions passed in with the first argument being a pointer
165*2264Sjacobs * to the current item in the list and the second argument being a va_list
166*2264Sjacobs * containing the rest of arguments used to call list_iterate(). The
167*2264Sjacobs * calling fuction should be declared: int func(type *, va_list). The
168*2264Sjacobs * return results are all added together and the sum is returned from
169*2264Sjacobs * list_iterate().
170*2264Sjacobs */
171*2264Sjacobs int
list_iterate(void ** list,int (* vfunc)(void *,va_list),...)172*2264Sjacobs list_iterate(void **list, int (*vfunc)(void *, va_list), ...)
173*2264Sjacobs {
174*2264Sjacobs int current = 0,
175*2264Sjacobs rc = 0;
176*2264Sjacobs
177*2264Sjacobs #ifdef DEBUG
178*2264Sjacobs syslog(LOG_DEBUG, "list_iterate(0x%x, 0x%x)", list, vfunc);
179*2264Sjacobs #endif
180*2264Sjacobs if (list != NULL)
181*2264Sjacobs while (list[current] != NULL) {
182*2264Sjacobs va_list ap;
183*2264Sjacobs
184*2264Sjacobs va_start(ap, (vfunc));
185*2264Sjacobs rc += (vfunc)(list[current++], ap);
186*2264Sjacobs va_end(ap);
187*2264Sjacobs }
188*2264Sjacobs return (rc);
189*2264Sjacobs }
190