1 /* $NetBSD: stringlist.c,v 1.13 2008/04/28 20:22:59 martin Exp $ 2 3 * Copyright (c) 1994, 1999 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Christos Zoulas. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 #if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */ 31 #pragma warning ( disable : 4018 ) 32 #endif 33 34 #include <sys/cdefs.h> 35 #if defined(LIBC_SCCS) && !defined(lint) 36 __RCSID("$NetBSD: stringlist.c,v 1.13 2008/04/28 20:22:59 martin Exp $"); 37 #endif /* LIBC_SCCS and not lint */ 38 39 #include <assert.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <stringlist.h> 44 45 #ifdef __weak_alias 46 __weak_alias(sl_add,_sl_add) 47 __weak_alias(sl_find,_sl_find) 48 __weak_alias(sl_free,_sl_free) 49 __weak_alias(sl_init,_sl_init) 50 __weak_alias(sl_delete,_sl_delete) 51 #endif 52 53 #define _SL_CHUNKSIZE 20 54 55 /* 56 * sl_init(): Initialize a string list 57 */ 58 StringList * 59 sl_init(void) 60 { 61 StringList *sl; 62 63 sl = malloc(sizeof(StringList)); 64 if (sl == NULL) 65 return NULL; 66 67 sl->sl_cur = 0; 68 sl->sl_max = _SL_CHUNKSIZE; 69 sl->sl_str = malloc(sl->sl_max * sizeof(char *)); 70 if (sl->sl_str == NULL) { 71 free(sl); 72 sl = NULL; 73 } 74 return sl; 75 } 76 77 78 /* 79 * sl_add(): Add an item to the string list 80 */ 81 int 82 sl_add(StringList *sl, char *name) 83 { 84 85 _DIAGASSERT(sl != NULL); 86 87 if (sl->sl_cur == sl->sl_max - 1) { 88 char **new; 89 90 new = realloc(sl->sl_str, 91 (sl->sl_max + _SL_CHUNKSIZE) * sizeof(char *)); 92 if (new == NULL) 93 return -1; 94 sl->sl_max += _SL_CHUNKSIZE; 95 sl->sl_str = new; 96 } 97 sl->sl_str[sl->sl_cur++] = name; 98 return 0; 99 } 100 101 102 /* 103 * sl_free(): Free a stringlist 104 */ 105 void 106 sl_free(StringList *sl, int all) 107 { 108 size_t i; 109 110 if (sl == NULL) 111 return; 112 if (sl->sl_str) { 113 if (all) 114 for (i = 0; i < sl->sl_cur; i++) 115 free(sl->sl_str[i]); 116 free(sl->sl_str); 117 } 118 free(sl); 119 } 120 121 122 /* 123 * sl_find(): Find a name in the string list 124 */ 125 char * 126 sl_find(StringList *sl, const char *name) 127 { 128 size_t i; 129 130 _DIAGASSERT(sl != NULL); 131 132 for (i = 0; i < sl->sl_cur; i++) 133 if (strcmp(sl->sl_str[i], name) == 0) 134 return sl->sl_str[i]; 135 136 return NULL; 137 } 138 139 int 140 sl_delete(StringList *sl, const char *name, int all) 141 { 142 size_t i, j; 143 144 for (i = 0; i < sl->sl_cur; i++) 145 if (strcmp(sl->sl_str[i], name) == 0) { 146 if (all) 147 free(sl->sl_str[i]); 148 for (j = i + 1; j < sl->sl_cur; j++) 149 sl->sl_str[j - 1] = sl->sl_str[j]; 150 sl->sl_str[--sl->sl_cur] = NULL; 151 return 0; 152 } 153 return -1; 154 } 155 156