17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5355b4669Sjacobs  * Common Development and Distribution License (the "License").
6355b4669Sjacobs  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21355b4669Sjacobs 
227c478bd9Sstevel@tonic-gate /*
23*425d6edcSjacobs  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25355b4669Sjacobs  *
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
28355b4669Sjacobs /* $Id: list.c 146 2006-03-24 00:26:54Z njacobs $ */
29355b4669Sjacobs 
307c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <stdlib.h>
337c478bd9Sstevel@tonic-gate #include <stdarg.h>
347c478bd9Sstevel@tonic-gate #include <errno.h>
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate static int __list_increment = 16;
377c478bd9Sstevel@tonic-gate 
38*425d6edcSjacobs #define	LIST_SIZE(x)	((((x) / __list_increment) + 1) * __list_increment)
39*425d6edcSjacobs 
407c478bd9Sstevel@tonic-gate int
list_append(void *** list,void * item)417c478bd9Sstevel@tonic-gate list_append(void ***list, void *item)
427c478bd9Sstevel@tonic-gate {
437c478bd9Sstevel@tonic-gate 	int count;
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate 	if ((list == NULL) || (item == NULL)) {
467c478bd9Sstevel@tonic-gate 		errno = EINVAL;
477c478bd9Sstevel@tonic-gate 		return (-1);
487c478bd9Sstevel@tonic-gate 	}
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate 	if (item != NULL) {
517c478bd9Sstevel@tonic-gate 		if (*list == NULL)
527c478bd9Sstevel@tonic-gate 			*list = (void **)calloc(__list_increment,
53*425d6edcSjacobs 			    sizeof (void *));
547c478bd9Sstevel@tonic-gate 
55*425d6edcSjacobs 		for (count = 0; (*list)[count] != NULL; count++)
56*425d6edcSjacobs 			;
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate 		if ((count + 1) % __list_increment == 0) { /* expand the list */
597c478bd9Sstevel@tonic-gate 			void **new_list = NULL;
60*425d6edcSjacobs 			int new_size = LIST_SIZE(count + 1);
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 			new_list = (void **)calloc(new_size, sizeof (void *));
630a44ef6dSjacobs 			if (new_list == NULL)
640a44ef6dSjacobs 				return (-1);
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate 			for (count = 0; (*list)[count] != NULL; count++)
677c478bd9Sstevel@tonic-gate 				new_list[count] = (*list)[count];
687c478bd9Sstevel@tonic-gate 			free(*list);
697c478bd9Sstevel@tonic-gate 			*list = new_list;
707c478bd9Sstevel@tonic-gate 		}
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 		(*list)[count] = item;
737c478bd9Sstevel@tonic-gate 	}
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	return (0);
767c478bd9Sstevel@tonic-gate }
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate /*
797c478bd9Sstevel@tonic-gate  *  list_concatenate() takes in two NULL terminated lists of items (type **)
807c478bd9Sstevel@tonic-gate  *      and creates a new list with items from list2 appended on the end of
817c478bd9Sstevel@tonic-gate  *      the list of items from list1.  The result is a list (type **).  If
827c478bd9Sstevel@tonic-gate  *      there is a failure, -1 is returned.
837c478bd9Sstevel@tonic-gate  */
847c478bd9Sstevel@tonic-gate int
list_concatenate(void *** result,void ** list2)857c478bd9Sstevel@tonic-gate list_concatenate(void ***result, void **list2)
867c478bd9Sstevel@tonic-gate {
877c478bd9Sstevel@tonic-gate 	void    **list1;
88*425d6edcSjacobs 	int	size1 = 0;
89*425d6edcSjacobs 	int	size2 = 0;
90*425d6edcSjacobs 	int	new_size = 0;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	if ((result == NULL) || ((*result == NULL) && (list2 == NULL))) {
937c478bd9Sstevel@tonic-gate 		errno = EINVAL;
947c478bd9Sstevel@tonic-gate 		return (-1);
957c478bd9Sstevel@tonic-gate 	}
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	list1 = *result;
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	if (list1 != NULL)
100*425d6edcSjacobs 		for (size1 = 0; list1[size1] != NULL; size1++)
101*425d6edcSjacobs 			;
1027c478bd9Sstevel@tonic-gate 	if (list2 != NULL)
103*425d6edcSjacobs 		for (size2 = 0; list2[size2] != NULL; size2++)
104*425d6edcSjacobs 			;
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	/* list1 + list2 padded to a multiple of _list_increment */
107*425d6edcSjacobs 	new_size = LIST_SIZE(size1 + size2);
1087c478bd9Sstevel@tonic-gate 
109*425d6edcSjacobs 	if ((*result = (void **)calloc((new_size), sizeof (void *))) != NULL) {
1107c478bd9Sstevel@tonic-gate 		int count = 0;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 		if (list1 != NULL)
1137c478bd9Sstevel@tonic-gate 			for (size1 = 0; list1[size1] != NULL; size1++)
1147c478bd9Sstevel@tonic-gate 				(*result)[count++] = list1[size1];
1157c478bd9Sstevel@tonic-gate 		if (list2 != NULL)
1167c478bd9Sstevel@tonic-gate 			for (size2 = 0; list2[size2] != NULL; size2++)
1177c478bd9Sstevel@tonic-gate 				(*result)[count++] = list2[size2];
1187c478bd9Sstevel@tonic-gate 		free(list1);
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	return (0);
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate /*
1257c478bd9Sstevel@tonic-gate  *  list_locate() iterates through the list passed in and uses the comparison
1267c478bd9Sstevel@tonic-gate  *      routine and element passed in to find an element in the list.  It
1277c478bd9Sstevel@tonic-gate  *      returns the first element matched, or NULL if none exists
1287c478bd9Sstevel@tonic-gate  */
1297c478bd9Sstevel@tonic-gate void *
list_locate(void ** list,int (* compare)(void *,void *),void * element)1307c478bd9Sstevel@tonic-gate list_locate(void **list, int (*compare)(void *, void *), void *element)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 	int current = 0;
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	if ((list != NULL) && (element != NULL))
1357c478bd9Sstevel@tonic-gate 		for (current = 0; list[current] != NULL; current++)
1367c478bd9Sstevel@tonic-gate 			if ((compare)(list[current], element) == 0)
1377c478bd9Sstevel@tonic-gate 				return (list[current]);
1387c478bd9Sstevel@tonic-gate 	return (NULL);
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate void
list_remove(void *** list,void * item)1420a44ef6dSjacobs list_remove(void ***list, void *item)
1437c478bd9Sstevel@tonic-gate {
144*425d6edcSjacobs 	int i = 0, count;
1450a44ef6dSjacobs 
146d978af5cSjacobs 	if ((list == NULL) || (*list == NULL) || (item == NULL))
147d978af5cSjacobs 		return;
1480a44ef6dSjacobs 
149*425d6edcSjacobs 	/* size the original list */
150*425d6edcSjacobs 	for (count = 0; (*list)[count] != NULL; count++)
151*425d6edcSjacobs 		if ((*list)[count] == item) {	/* mark the location of item */
152*425d6edcSjacobs 			i = count;
153*425d6edcSjacobs 			item = NULL;
154*425d6edcSjacobs 		}
155d978af5cSjacobs 
156*425d6edcSjacobs 	/* if found, remove it */
157*425d6edcSjacobs 	if (item == NULL) {
158*425d6edcSjacobs 		/* shift the list over the item */
159*425d6edcSjacobs 		for (++i; ((*list)[i] != NULL); i++)
160*425d6edcSjacobs 			(*list)[i-1] = (*list)[i];
161*425d6edcSjacobs 		(*list)[i-1] = NULL;
1620a44ef6dSjacobs 	}
1630a44ef6dSjacobs 
164*425d6edcSjacobs 	/* if found, removed, and list should shrink, shrink it */
165*425d6edcSjacobs 	if ((item == NULL) && (LIST_SIZE(i) < LIST_SIZE(count))) {
166*425d6edcSjacobs 		void **tmp = (void **)calloc(LIST_SIZE(i), sizeof (void *));
167*425d6edcSjacobs 
168*425d6edcSjacobs 		if (tmp != NULL) {
169*425d6edcSjacobs 			for (i = 0; (*list)[i] != NULL; i++)
170*425d6edcSjacobs 				tmp[i] = (*list)[i];
171*425d6edcSjacobs 			free(*list);
172*425d6edcSjacobs 			*list = tmp;
173*425d6edcSjacobs 		}
1747c478bd9Sstevel@tonic-gate 	}
1757c478bd9Sstevel@tonic-gate }
176