1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 */ 27 28 /* $Id: list.c 146 2006-03-24 00:26:54Z njacobs $ */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /*LINTLIBRARY*/ 33 34 #include <stdlib.h> 35 #include <stdarg.h> 36 #include <errno.h> 37 38 static int __list_increment = 16; 39 40 #define LIST_SIZE(x) ((((x) / __list_increment) + 1) * __list_increment) 41 42 int 43 list_append(void ***list, void *item) 44 { 45 int count; 46 47 if ((list == NULL) || (item == NULL)) { 48 errno = EINVAL; 49 return (-1); 50 } 51 52 if (item != NULL) { 53 if (*list == NULL) 54 *list = (void **)calloc(__list_increment, 55 sizeof (void *)); 56 57 for (count = 0; (*list)[count] != NULL; count++) 58 ; 59 60 if ((count + 1) % __list_increment == 0) { /* expand the list */ 61 void **new_list = NULL; 62 int new_size = LIST_SIZE(count + 1); 63 64 new_list = (void **)calloc(new_size, sizeof (void *)); 65 if (new_list == NULL) 66 return (-1); 67 68 for (count = 0; (*list)[count] != NULL; count++) 69 new_list[count] = (*list)[count]; 70 free(*list); 71 *list = new_list; 72 } 73 74 (*list)[count] = item; 75 } 76 77 return (0); 78 } 79 80 /* 81 * list_concatenate() takes in two NULL terminated lists of items (type **) 82 * and creates a new list with items from list2 appended on the end of 83 * the list of items from list1. The result is a list (type **). If 84 * there is a failure, -1 is returned. 85 */ 86 int 87 list_concatenate(void ***result, void **list2) 88 { 89 void **list1; 90 int size1 = 0; 91 int size2 = 0; 92 int new_size = 0; 93 94 if ((result == NULL) || ((*result == NULL) && (list2 == NULL))) { 95 errno = EINVAL; 96 return (-1); 97 } 98 99 list1 = *result; 100 101 if (list1 != NULL) 102 for (size1 = 0; list1[size1] != NULL; size1++) 103 ; 104 if (list2 != NULL) 105 for (size2 = 0; list2[size2] != NULL; size2++) 106 ; 107 108 /* list1 + list2 padded to a multiple of _list_increment */ 109 new_size = LIST_SIZE(size1 + size2); 110 111 if ((*result = (void **)calloc((new_size), sizeof (void *))) != NULL) { 112 int count = 0; 113 114 if (list1 != NULL) 115 for (size1 = 0; list1[size1] != NULL; size1++) 116 (*result)[count++] = list1[size1]; 117 if (list2 != NULL) 118 for (size2 = 0; list2[size2] != NULL; size2++) 119 (*result)[count++] = list2[size2]; 120 free(list1); 121 } 122 123 return (0); 124 } 125 126 /* 127 * list_locate() iterates through the list passed in and uses the comparison 128 * routine and element passed in to find an element in the list. It 129 * returns the first element matched, or NULL if none exists 130 */ 131 void * 132 list_locate(void **list, int (*compare)(void *, void *), void *element) 133 { 134 int current = 0; 135 136 if ((list != NULL) && (element != NULL)) 137 for (current = 0; list[current] != NULL; current++) 138 if ((compare)(list[current], element) == 0) 139 return (list[current]); 140 return (NULL); 141 } 142 143 void 144 list_remove(void ***list, void *item) 145 { 146 int i = 0, count; 147 148 if ((list == NULL) || (*list == NULL) || (item == NULL)) 149 return; 150 151 /* size the original list */ 152 for (count = 0; (*list)[count] != NULL; count++) 153 if ((*list)[count] == item) { /* mark the location of item */ 154 i = count; 155 item = NULL; 156 } 157 158 /* if found, remove it */ 159 if (item == NULL) { 160 /* shift the list over the item */ 161 for (++i; ((*list)[i] != NULL); i++) 162 (*list)[i-1] = (*list)[i]; 163 (*list)[i-1] = NULL; 164 } 165 166 /* if found, removed, and list should shrink, shrink it */ 167 if ((item == NULL) && (LIST_SIZE(i) < LIST_SIZE(count))) { 168 void **tmp = (void **)calloc(LIST_SIZE(i), sizeof (void *)); 169 170 if (tmp != NULL) { 171 for (i = 0; (*list)[i] != NULL; i++) 172 tmp[i] = (*list)[i]; 173 free(*list); 174 *list = tmp; 175 } 176 } 177 } 178