12264Sjacobs /*
22264Sjacobs * CDDL HEADER START
32264Sjacobs *
42264Sjacobs * The contents of this file are subject to the terms of the
52264Sjacobs * Common Development and Distribution License (the "License").
62264Sjacobs * You may not use this file except in compliance with the License.
72264Sjacobs *
82264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92264Sjacobs * or http://www.opensolaris.org/os/licensing.
102264Sjacobs * See the License for the specific language governing permissions
112264Sjacobs * and limitations under the License.
122264Sjacobs *
132264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each
142264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152264Sjacobs * If applicable, add the following below this CDDL HEADER, with the
162264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying
172264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner]
182264Sjacobs *
192264Sjacobs * CDDL HEADER END
202264Sjacobs */
212264Sjacobs
222264Sjacobs /*
23*6585Sjacobs * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
242264Sjacobs * Use is subject to license terms.
252264Sjacobs *
262264Sjacobs */
272264Sjacobs
282264Sjacobs /* $Id: list.c 146 2006-03-24 00:26:54Z njacobs $ */
292264Sjacobs
302264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI"
312264Sjacobs
322264Sjacobs /*LINTLIBRARY*/
332264Sjacobs
342264Sjacobs #include <stdlib.h>
352264Sjacobs #include <stdarg.h>
362264Sjacobs #include <errno.h>
372264Sjacobs
382264Sjacobs static int __list_increment = 16;
392264Sjacobs
40*6585Sjacobs #define LIST_SIZE(x) ((((x) / __list_increment) + 1) * __list_increment)
41*6585Sjacobs
422264Sjacobs int
list_append(void *** list,void * item)432264Sjacobs list_append(void ***list, void *item)
442264Sjacobs {
452264Sjacobs int count;
462264Sjacobs
472264Sjacobs if ((list == NULL) || (item == NULL)) {
482264Sjacobs errno = EINVAL;
492264Sjacobs return (-1);
502264Sjacobs }
512264Sjacobs
522264Sjacobs if (item != NULL) {
532264Sjacobs if (*list == NULL)
542264Sjacobs *list = (void **)calloc(__list_increment,
55*6585Sjacobs sizeof (void *));
562264Sjacobs
57*6585Sjacobs for (count = 0; (*list)[count] != NULL; count++)
58*6585Sjacobs ;
592264Sjacobs
602264Sjacobs if ((count + 1) % __list_increment == 0) { /* expand the list */
612264Sjacobs void **new_list = NULL;
62*6585Sjacobs int new_size = LIST_SIZE(count + 1);
632264Sjacobs
642264Sjacobs new_list = (void **)calloc(new_size, sizeof (void *));
653125Sjacobs if (new_list == NULL)
663125Sjacobs return (-1);
672264Sjacobs
682264Sjacobs for (count = 0; (*list)[count] != NULL; count++)
692264Sjacobs new_list[count] = (*list)[count];
702264Sjacobs free(*list);
712264Sjacobs *list = new_list;
722264Sjacobs }
732264Sjacobs
742264Sjacobs (*list)[count] = item;
752264Sjacobs }
762264Sjacobs
772264Sjacobs return (0);
782264Sjacobs }
792264Sjacobs
802264Sjacobs /*
812264Sjacobs * list_concatenate() takes in two NULL terminated lists of items (type **)
822264Sjacobs * and creates a new list with items from list2 appended on the end of
832264Sjacobs * the list of items from list1. The result is a list (type **). If
842264Sjacobs * there is a failure, -1 is returned.
852264Sjacobs */
862264Sjacobs int
list_concatenate(void *** result,void ** list2)872264Sjacobs list_concatenate(void ***result, void **list2)
882264Sjacobs {
892264Sjacobs void **list1;
90*6585Sjacobs int size1 = 0;
91*6585Sjacobs int size2 = 0;
92*6585Sjacobs int new_size = 0;
932264Sjacobs
942264Sjacobs if ((result == NULL) || ((*result == NULL) && (list2 == NULL))) {
952264Sjacobs errno = EINVAL;
962264Sjacobs return (-1);
972264Sjacobs }
982264Sjacobs
992264Sjacobs list1 = *result;
1002264Sjacobs
1012264Sjacobs if (list1 != NULL)
102*6585Sjacobs for (size1 = 0; list1[size1] != NULL; size1++)
103*6585Sjacobs ;
1042264Sjacobs if (list2 != NULL)
105*6585Sjacobs for (size2 = 0; list2[size2] != NULL; size2++)
106*6585Sjacobs ;
1072264Sjacobs
1082264Sjacobs /* list1 + list2 padded to a multiple of _list_increment */
109*6585Sjacobs new_size = LIST_SIZE(size1 + size2);
1102264Sjacobs
111*6585Sjacobs if ((*result = (void **)calloc((new_size), sizeof (void *))) != NULL) {
1122264Sjacobs int count = 0;
1132264Sjacobs
1142264Sjacobs if (list1 != NULL)
1152264Sjacobs for (size1 = 0; list1[size1] != NULL; size1++)
1162264Sjacobs (*result)[count++] = list1[size1];
1172264Sjacobs if (list2 != NULL)
1182264Sjacobs for (size2 = 0; list2[size2] != NULL; size2++)
1192264Sjacobs (*result)[count++] = list2[size2];
1202264Sjacobs free(list1);
1212264Sjacobs }
1222264Sjacobs
1232264Sjacobs return (0);
1242264Sjacobs }
1252264Sjacobs
1262264Sjacobs /*
1272264Sjacobs * list_locate() iterates through the list passed in and uses the comparison
1282264Sjacobs * routine and element passed in to find an element in the list. It
1292264Sjacobs * returns the first element matched, or NULL if none exists
1302264Sjacobs */
1312264Sjacobs void *
list_locate(void ** list,int (* compare)(void *,void *),void * element)1322264Sjacobs list_locate(void **list, int (*compare)(void *, void *), void *element)
1332264Sjacobs {
1342264Sjacobs int current = 0;
1352264Sjacobs
1362264Sjacobs if ((list != NULL) && (element != NULL))
1372264Sjacobs for (current = 0; list[current] != NULL; current++)
1382264Sjacobs if ((compare)(list[current], element) == 0)
1392264Sjacobs return (list[current]);
1402264Sjacobs return (NULL);
1412264Sjacobs }
1422264Sjacobs
1432264Sjacobs void
list_remove(void *** list,void * item)1443125Sjacobs list_remove(void ***list, void *item)
1452264Sjacobs {
146*6585Sjacobs int i = 0, count;
1472264Sjacobs
1483127Sjacobs if ((list == NULL) || (*list == NULL) || (item == NULL))
1493127Sjacobs return;
1502264Sjacobs
151*6585Sjacobs /* size the original list */
152*6585Sjacobs for (count = 0; (*list)[count] != NULL; count++)
153*6585Sjacobs if ((*list)[count] == item) { /* mark the location of item */
154*6585Sjacobs i = count;
155*6585Sjacobs item = NULL;
156*6585Sjacobs }
1572264Sjacobs
158*6585Sjacobs /* if found, remove it */
159*6585Sjacobs if (item == NULL) {
160*6585Sjacobs /* shift the list over the item */
161*6585Sjacobs for (++i; ((*list)[i] != NULL); i++)
162*6585Sjacobs (*list)[i-1] = (*list)[i];
163*6585Sjacobs (*list)[i-1] = NULL;
1643125Sjacobs }
1653125Sjacobs
166*6585Sjacobs /* if found, removed, and list should shrink, shrink it */
167*6585Sjacobs if ((item == NULL) && (LIST_SIZE(i) < LIST_SIZE(count))) {
168*6585Sjacobs void **tmp = (void **)calloc(LIST_SIZE(i), sizeof (void *));
169*6585Sjacobs
170*6585Sjacobs if (tmp != NULL) {
171*6585Sjacobs for (i = 0; (*list)[i] != NULL; i++)
172*6585Sjacobs tmp[i] = (*list)[i];
173*6585Sjacobs free(*list);
174*6585Sjacobs *list = tmp;
175*6585Sjacobs }
1762264Sjacobs }
1772264Sjacobs }
178