xref: /onnv-gate/usr/src/lib/print/libpapi-common/common/list.c (revision 6585:167cffc8d7fd)
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