1*3249d3dcSchristos /* $NetBSD: stringlist.c,v 1.15 2022/03/12 17:31:39 christos Exp $ */
2f694f3b1Slukem
39f731168Slukem /*-
49f731168Slukem * Copyright (c) 1994, 1999 The NetBSD Foundation, Inc.
5f694f3b1Slukem * All rights reserved.
6f694f3b1Slukem *
79f731168Slukem * This code is derived from software contributed to The NetBSD Foundation
89f731168Slukem * by Christos Zoulas.
99f731168Slukem *
10f694f3b1Slukem * Redistribution and use in source and binary forms, with or without
11f694f3b1Slukem * modification, are permitted provided that the following conditions
12f694f3b1Slukem * are met:
13f694f3b1Slukem * 1. Redistributions of source code must retain the above copyright
14f694f3b1Slukem * notice, this list of conditions and the following disclaimer.
15f694f3b1Slukem * 2. Redistributions in binary form must reproduce the above copyright
16f694f3b1Slukem * notice, this list of conditions and the following disclaimer in the
17f694f3b1Slukem * documentation and/or other materials provided with the distribution.
18f694f3b1Slukem *
199f731168Slukem * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
209f731168Slukem * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
219f731168Slukem * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
229f731168Slukem * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
239f731168Slukem * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
249f731168Slukem * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
259f731168Slukem * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
269f731168Slukem * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
279f731168Slukem * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
289f731168Slukem * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
299f731168Slukem * POSSIBILITY OF SUCH DAMAGE.
30f694f3b1Slukem */
31f694f3b1Slukem
3247d1af8aSchristos #include <sys/cdefs.h>
33f694f3b1Slukem #if defined(LIBC_SCCS) && !defined(lint)
34*3249d3dcSchristos __RCSID("$NetBSD: stringlist.c,v 1.15 2022/03/12 17:31:39 christos Exp $");
35f694f3b1Slukem #endif /* LIBC_SCCS and not lint */
36f694f3b1Slukem
3747d1af8aSchristos #include "namespace.h"
38b48252f3Slukem
39b48252f3Slukem #include <assert.h>
40f694f3b1Slukem #include <err.h>
4106f2d206Schristos #include <errno.h>
42b48252f3Slukem #include <stdio.h>
43f694f3b1Slukem #include <stdlib.h>
44b48252f3Slukem #include <string.h>
45f694f3b1Slukem #include <stringlist.h>
46f694f3b1Slukem
4743fa6fe3Sjtc #ifdef __weak_alias
__weak_alias(sl_add,_sl_add)4860549036Smycroft __weak_alias(sl_add,_sl_add)
4960549036Smycroft __weak_alias(sl_find,_sl_find)
5060549036Smycroft __weak_alias(sl_free,_sl_free)
5160549036Smycroft __weak_alias(sl_init,_sl_init)
5236a33408Schristos __weak_alias(sl_delete,_sl_delete)
5343fa6fe3Sjtc #endif
5443fa6fe3Sjtc
55f694f3b1Slukem #define _SL_CHUNKSIZE 20
56f694f3b1Slukem
57f694f3b1Slukem /*
58f694f3b1Slukem * sl_init(): Initialize a string list
59f694f3b1Slukem */
60f694f3b1Slukem StringList *
616826db0fSchristos sl_init(void)
62f694f3b1Slukem {
63b48252f3Slukem StringList *sl;
64b48252f3Slukem
65b48252f3Slukem sl = malloc(sizeof(StringList));
66f694f3b1Slukem if (sl == NULL)
676826db0fSchristos return NULL;
68f694f3b1Slukem
69f694f3b1Slukem sl->sl_cur = 0;
70f694f3b1Slukem sl->sl_max = _SL_CHUNKSIZE;
7106f2d206Schristos sl->sl_str = NULL;
72*3249d3dcSchristos errno = reallocarr(&sl->sl_str, sl->sl_max, sizeof(*sl->sl_str));
7306f2d206Schristos if (errno) {
74*3249d3dcSchristos int serrno = errno;
7546a687b1Slukem free(sl);
76*3249d3dcSchristos errno = serrno;
7746a687b1Slukem sl = NULL;
7846a687b1Slukem }
796826db0fSchristos return sl;
80f694f3b1Slukem }
81f694f3b1Slukem
82f694f3b1Slukem
83f694f3b1Slukem /*
84f694f3b1Slukem * sl_add(): Add an item to the string list
85f694f3b1Slukem */
8646a687b1Slukem int
sl_add(StringList * sl,char * name)876826db0fSchristos sl_add(StringList *sl, char *name)
88f694f3b1Slukem {
89b48252f3Slukem
90b48252f3Slukem _DIAGASSERT(sl != NULL);
91b48252f3Slukem
92f694f3b1Slukem if (sl->sl_cur == sl->sl_max - 1) {
9306f2d206Schristos char **new = sl->sl_str;
9446a687b1Slukem
9506f2d206Schristos errno = reallocarr(&new, (sl->sl_max + _SL_CHUNKSIZE),
96*3249d3dcSchristos sizeof(*new));
9706f2d206Schristos if (errno)
986826db0fSchristos return -1;
996e75e4cbSenami sl->sl_max += _SL_CHUNKSIZE;
10046a687b1Slukem sl->sl_str = new;
101f694f3b1Slukem }
102f694f3b1Slukem sl->sl_str[sl->sl_cur++] = name;
1036826db0fSchristos return 0;
104f694f3b1Slukem }
105f694f3b1Slukem
106f694f3b1Slukem
107f694f3b1Slukem /*
108f694f3b1Slukem * sl_free(): Free a stringlist
109f694f3b1Slukem */
110f694f3b1Slukem void
sl_free(StringList * sl,int all)1116826db0fSchristos sl_free(StringList *sl, int all)
112f694f3b1Slukem {
113f694f3b1Slukem size_t i;
114f694f3b1Slukem
115f694f3b1Slukem if (sl == NULL)
116f694f3b1Slukem return;
117f694f3b1Slukem if (sl->sl_str) {
118f694f3b1Slukem if (all)
119f694f3b1Slukem for (i = 0; i < sl->sl_cur; i++)
120f694f3b1Slukem free(sl->sl_str[i]);
121f694f3b1Slukem free(sl->sl_str);
122f694f3b1Slukem }
123f694f3b1Slukem free(sl);
124f694f3b1Slukem }
125f694f3b1Slukem
126f694f3b1Slukem
127f694f3b1Slukem /*
128f694f3b1Slukem * sl_find(): Find a name in the string list
129f694f3b1Slukem */
130f694f3b1Slukem char *
sl_find(StringList * sl,const char * name)1316826db0fSchristos sl_find(StringList *sl, const char *name)
132f694f3b1Slukem {
133f694f3b1Slukem size_t i;
134f694f3b1Slukem
135b48252f3Slukem _DIAGASSERT(sl != NULL);
136b48252f3Slukem
137f694f3b1Slukem for (i = 0; i < sl->sl_cur; i++)
138f694f3b1Slukem if (strcmp(sl->sl_str[i], name) == 0)
1396826db0fSchristos return sl->sl_str[i];
140f694f3b1Slukem
1416826db0fSchristos return NULL;
142f694f3b1Slukem }
1436826db0fSchristos
1446826db0fSchristos int
sl_delete(StringList * sl,const char * name,int all)1456826db0fSchristos sl_delete(StringList *sl, const char *name, int all)
1466826db0fSchristos {
1476826db0fSchristos size_t i, j;
1486826db0fSchristos
1496826db0fSchristos for (i = 0; i < sl->sl_cur; i++)
1506826db0fSchristos if (strcmp(sl->sl_str[i], name) == 0) {
1516826db0fSchristos if (all)
1526826db0fSchristos free(sl->sl_str[i]);
1536826db0fSchristos for (j = i + 1; j < sl->sl_cur; j++)
1546826db0fSchristos sl->sl_str[j - 1] = sl->sl_str[j];
1556826db0fSchristos sl->sl_str[--sl->sl_cur] = NULL;
1566826db0fSchristos return 0;
1576826db0fSchristos }
1586826db0fSchristos return -1;
1596826db0fSchristos }
1606826db0fSchristos
161