#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: stringlist.c,v 1.15 2022/03/12 17:31:39 christos Exp $");
#endif
#include "namespace.h"
#include <assert.h>
#include <err.h>
#include <errno.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
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 = NULL;
errno = reallocarr(&sl->sl_str, sl->sl_max, sizeof(*sl->sl_str));
if (errno) {
int serrno = errno;
free(sl);
errno = serrno;
sl = NULL;
}
return sl;
}
int
sl_add(StringList *sl, char *name)
{
_DIAGASSERT(sl != NULL);
if (sl->sl_cur == sl->sl_max - 1) {
char **new = sl->sl_str;
errno = reallocarr(&new, (sl->sl_max + _SL_CHUNKSIZE),
sizeof(*new));
if (errno)
return -1;
sl->sl_max += _SL_CHUNKSIZE;
sl->sl_str = new;
}
sl->sl_str[sl->sl_cur++] = name;
return 0;
}
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);
}
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;
}