| /* $NetBSD: stringlist.c,v 1.13 2008/04/28 20:22:59 martin Exp $ | |
| * Copyright (c) 1994, 1999 The NetBSD Foundation, Inc. | |
| * All rights reserved. | |
| * | |
| * This code is derived from software contributed to The NetBSD Foundation | |
| * by Christos Zoulas. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions | |
| * are met: | |
| * 1. Redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer. | |
| * 2. Redistributions in binary form must reproduce the above copyright | |
| * notice, this list of conditions and the following disclaimer in the | |
| * documentation and/or other materials provided with the distribution. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
| * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| * POSSIBILITY OF SUCH DAMAGE. | |
| */ | |
| #if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */ | |
| #pragma warning ( disable : 4018 ) | |
| #endif | |
| #include <sys/cdefs.h> | |
| #if defined(LIBC_SCCS) && !defined(lint) | |
| __RCSID("$NetBSD: stringlist.c,v 1.13 2008/04/28 20:22:59 martin Exp $"); | |
| #endif /* LIBC_SCCS and not lint */ | |
| #include <assert.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <stringlist.h> | |
| #ifdef __weak_alias | |
| __weak_alias(sl_add,_sl_add) | |
| __weak_alias(sl_find,_sl_find) | |
| __weak_alias(sl_free,_sl_free) | |
| __weak_alias(sl_init,_sl_init) | |
| __weak_alias(sl_delete,_sl_delete) | |
| #endif | |
| #define _SL_CHUNKSIZE 20 | |
| /* | |
| * sl_init(): Initialize a string list | |
| */ | |
| StringList * | |
| sl_init(void) | |
| { | |
| StringList *sl; | |
| sl = malloc(sizeof(StringList)); | |
| if (sl == NULL) | |
| return NULL; | |
| sl->sl_cur = 0; | |
| sl->sl_max = _SL_CHUNKSIZE; | |
| sl->sl_str = malloc(sl->sl_max * sizeof(char *)); | |
| if (sl->sl_str == NULL) { | |
| free(sl); | |
| sl = NULL; | |
| } | |
| return sl; | |
| } | |
| /* | |
| * sl_add(): Add an item to the string list | |
| */ | |
| int | |
| sl_add(StringList *sl, char *name) | |
| { | |
| _DIAGASSERT(sl != NULL); | |
| if (sl->sl_cur == sl->sl_max - 1) { | |
| char **new; | |
| new = realloc(sl->sl_str, | |
| (sl->sl_max + _SL_CHUNKSIZE) * sizeof(char *)); | |
| if (new == NULL) | |
| return -1; | |
| sl->sl_max += _SL_CHUNKSIZE; | |
| sl->sl_str = new; | |
| } | |
| sl->sl_str[sl->sl_cur++] = name; | |
| return 0; | |
| } | |
| /* | |
| * sl_free(): Free a stringlist | |
| */ | |
| void | |
| sl_free(StringList *sl, int all) | |
| { | |
| size_t i; | |
| if (sl == NULL) | |
| return; | |
| if (sl->sl_str) { | |
| if (all) | |
| for (i = 0; i < sl->sl_cur; i++) | |
| free(sl->sl_str[i]); | |
| free(sl->sl_str); | |
| } | |
| free(sl); | |
| } | |
| /* | |
| * sl_find(): Find a name in the string list | |
| */ | |
| char * | |
| sl_find(StringList *sl, const char *name) | |
| { | |
| size_t i; | |
| _DIAGASSERT(sl != NULL); | |
| for (i = 0; i < sl->sl_cur; i++) | |
| if (strcmp(sl->sl_str[i], name) == 0) | |
| return sl->sl_str[i]; | |
| return NULL; | |
| } | |
| int | |
| sl_delete(StringList *sl, const char *name, int all) | |
| { | |
| size_t i, j; | |
| for (i = 0; i < sl->sl_cur; i++) | |
| if (strcmp(sl->sl_str[i], name) == 0) { | |
| if (all) | |
| free(sl->sl_str[i]); | |
| for (j = i + 1; j < sl->sl_cur; j++) | |
| sl->sl_str[j - 1] = sl->sl_str[j]; | |
| sl->sl_str[--sl->sl_cur] = NULL; | |
| return 0; | |
| } | |
| return -1; | |
| } | |