xref: /onnv-gate/usr/src/lib/print/libprint/common/list.c (revision 2264:b2b9267d002d)
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