chiark / gitweb /
license: add GPLv2+ license blurbs everwhere
[elogind.git] / strv.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <string.h>
26
27 #include "util.h"
28 #include "strv.h"
29
30 char *strv_find(char **l, const char *name) {
31         assert(l);
32         assert(name);
33
34         for (; *l; l++)
35                 if (streq(*l, name))
36                         return *l;
37
38         return NULL;
39 }
40
41 void strv_free(char **l) {
42         char **k;
43
44         if (!l)
45                 return;
46
47         for (k = l; *k; k++)
48                 free(*k);
49
50         free(l);
51 }
52
53 char **strv_copy(char **l) {
54         char **r, **k;
55
56         if (!(r = new(char*, strv_length(l)+1)))
57                 return NULL;
58
59         for (k = r; *l; k++, l++)
60                 if (!(*k = strdup(*l)))
61                         goto fail;
62
63         *k = NULL;
64         return r;
65
66 fail:
67         for (k--, l--; k >= r; k--, l--)
68                 free(*k);
69
70         return NULL;
71 }
72
73 unsigned strv_length(char **l) {
74         unsigned n = 0;
75
76         if (!l)
77                 return 0;
78
79         for (; *l; l++)
80                 n++;
81
82         return n;
83 }
84
85 char **strv_new(const char *x, ...) {
86         const char *s;
87         char **a;
88         unsigned n = 0, i = 0;
89         va_list ap;
90
91         if (x) {
92                 n = 1;
93
94                 va_start(ap, x);
95
96                 while (va_arg(ap, const char*))
97                         n++;
98
99                 va_end(ap);
100         }
101
102         if (!(a = new(char*, n+1)))
103                 return NULL;
104
105         if (x) {
106                 if (!(a[i] = strdup(x))) {
107                         free(a);
108                         return NULL;
109                 }
110
111                 i++;
112
113                 va_start(ap, x);
114
115                 while ((s = va_arg(ap, const char*))) {
116                         if (!(a[i] = strdup(s)))
117                                 goto fail;
118
119                         i++;
120                 }
121
122                 va_end(ap);
123         }
124
125         a[i] = NULL;
126         return a;
127
128 fail:
129
130         for (; i > 0; i--)
131                 if (a[i-1])
132                         free(a[i-1]);
133
134         free(a);
135         return NULL;
136 }
137
138 char **strv_merge(char **a, char **b) {
139         char **r, **k;
140
141         if (!a)
142                 return strv_copy(b);
143
144         if (!b)
145                 return strv_copy(a);
146
147         if (!(r = new(char*, strv_length(a)+strv_length(b)+1)))
148                 return NULL;
149
150         for (k = r; *a; k++, a++)
151                 if (!(*k = strdup(*a)))
152                         goto fail;
153         for (; *b; k++, b++)
154                 if (!(*k = strdup(*b)))
155                         goto fail;
156
157         *k = NULL;
158         return r;
159
160 fail:
161         for (k--; k >= r; k--)
162                 free(*k);
163
164         return NULL;
165
166 }
167
168 bool strv_contains(char **l, const char *s) {
169         char **i;
170
171         STRV_FOREACH(i, l)
172                 if (streq(*i, s))
173                         return true;
174
175         return false;
176 }