Home | History | Annotate | Download | only in Stringlist
      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