Line data Source code
1 : /* stringlist.c - functions to handle a generic `list of strings' structure */
2 :
3 : /* Copyright (C) 2000-2002 Free Software Foundation, Inc.
4 :
5 : This file is part of GNU Bash, the Bourne Again SHell.
6 :
7 : Bash is free software: you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation, either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : Bash is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with Bash. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 :
23 : #if defined (HAVE_UNISTD_H)
24 : # include <unistd.h>
25 : #endif
26 :
27 : #include <stdio.h>
28 : #include <bashansi.h>
29 :
30 : #include "shell.h"
31 :
32 : #ifdef STRDUP
33 : # undef STRDUP
34 : #endif
35 : #define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
36 :
37 : /* Allocate a new STRINGLIST, with room for N strings. */
38 :
39 : STRINGLIST *
40 0 : strlist_create (n)
41 : int n;
42 : {
43 0 : STRINGLIST *ret;
44 0 : register int i;
45 :
46 0 : ret = (STRINGLIST *)xmalloc (sizeof (STRINGLIST));
47 0 : if (n)
48 : {
49 0 : ret->list = strvec_create (n+1);
50 0 : ret->list_size = n;
51 0 : for (i = 0; i < n; i++)
52 0 : ret->list[i] = (char *)NULL;
53 : }
54 : else
55 : {
56 0 : ret->list = (char **)NULL;
57 0 : ret->list_size = 0;
58 : }
59 0 : ret->list_len = 0;
60 0 : return ret;
61 : }
62 :
63 : STRINGLIST *
64 0 : strlist_resize (sl, n)
65 : STRINGLIST *sl;
66 : int n;
67 : {
68 0 : register int i;
69 :
70 0 : if (sl == 0)
71 0 : return (sl = strlist_create (n));
72 :
73 0 : if (n > sl->list_size)
74 : {
75 0 : sl->list = strvec_resize (sl->list, n + 1);
76 0 : for (i = sl->list_size; i <= n; i++)
77 0 : sl->list[i] = (char *)NULL;
78 0 : sl->list_size = n;
79 : }
80 : return sl;
81 : }
82 :
83 : void
84 0 : strlist_flush (sl)
85 : STRINGLIST *sl;
86 : {
87 0 : if (sl == 0 || sl->list == 0)
88 : return;
89 0 : strvec_flush (sl->list);
90 0 : sl->list_len = 0;
91 : }
92 :
93 : void
94 0 : strlist_dispose (sl)
95 : STRINGLIST *sl;
96 : {
97 0 : if (sl == 0)
98 : return;
99 0 : if (sl->list)
100 0 : strvec_dispose (sl->list);
101 0 : free (sl);
102 : }
103 :
104 : int
105 0 : strlist_remove (sl, s)
106 : STRINGLIST *sl;
107 : char *s;
108 : {
109 0 : int r;
110 :
111 0 : if (sl == 0 || sl->list == 0 || sl->list_len == 0)
112 : return 0;
113 :
114 0 : r = strvec_remove (sl->list, s);
115 0 : if (r)
116 0 : sl->list_len--;
117 : return r;
118 : }
119 :
120 : STRINGLIST *
121 0 : strlist_copy (sl)
122 : STRINGLIST *sl;
123 : {
124 0 : STRINGLIST *new;
125 0 : register int i;
126 :
127 0 : if (sl == 0)
128 : return ((STRINGLIST *)0);
129 0 : new = strlist_create (sl->list_size);
130 : /* I'd like to use strvec_copy, but that doesn't copy everything. */
131 0 : if (sl->list)
132 : {
133 0 : for (i = 0; i < sl->list_size; i++)
134 0 : new->list[i] = STRDUP (sl->list[i]);
135 : }
136 0 : new->list_size = sl->list_size;
137 0 : new->list_len = sl->list_len;
138 : /* just being careful */
139 0 : if (new->list)
140 0 : new->list[new->list_len] = (char *)NULL;
141 : return new;
142 : }
143 :
144 : /* Return a new STRINGLIST with everything from M1 and M2. */
145 :
146 : STRINGLIST *
147 0 : strlist_merge (m1, m2)
148 : STRINGLIST *m1, *m2;
149 : {
150 0 : STRINGLIST *sl;
151 0 : int i, n, l1, l2;
152 :
153 0 : l1 = m1 ? m1->list_len : 0;
154 0 : l2 = m2 ? m2->list_len : 0;
155 :
156 0 : sl = strlist_create (l1 + l2 + 1);
157 0 : for (i = n = 0; i < l1; i++, n++)
158 0 : sl->list[n] = STRDUP (m1->list[i]);
159 0 : for (i = 0; i < l2; i++, n++)
160 0 : sl->list[n] = STRDUP (m2->list[i]);
161 0 : sl->list_len = n;
162 0 : sl->list[n] = (char *)NULL;
163 0 : return (sl);
164 : }
165 :
166 : /* Make STRINGLIST M1 contain everything in M1 and M2. */
167 : STRINGLIST *
168 0 : strlist_append (m1, m2)
169 : STRINGLIST *m1, *m2;
170 : {
171 0 : register int i, n, len1, len2;
172 :
173 0 : if (m1 == 0)
174 0 : return (m2 ? strlist_copy (m2) : (STRINGLIST *)0);
175 :
176 0 : len1 = m1->list_len;
177 0 : len2 = m2 ? m2->list_len : 0;
178 :
179 0 : if (len2)
180 : {
181 0 : m1 = strlist_resize (m1, len1 + len2 + 1);
182 0 : for (i = 0, n = len1; i < len2; i++, n++)
183 0 : m1->list[n] = STRDUP (m2->list[i]);
184 0 : m1->list[n] = (char *)NULL;
185 0 : m1->list_len = n;
186 : }
187 :
188 : return m1;
189 : }
190 :
191 : STRINGLIST *
192 0 : strlist_prefix_suffix (sl, prefix, suffix)
193 : STRINGLIST *sl;
194 : char *prefix, *suffix;
195 : {
196 0 : int plen, slen, tlen, llen, i;
197 0 : char *t;
198 :
199 0 : if (sl == 0 || sl->list == 0 || sl->list_len == 0)
200 : return sl;
201 :
202 0 : plen = STRLEN (prefix);
203 0 : slen = STRLEN (suffix);
204 :
205 0 : if (plen == 0 && slen == 0)
206 : return (sl);
207 :
208 0 : for (i = 0; i < sl->list_len; i++)
209 : {
210 0 : llen = STRLEN (sl->list[i]);
211 0 : tlen = plen + llen + slen + 1;
212 0 : t = (char *)xmalloc (tlen + 1);
213 0 : if (plen)
214 0 : strcpy (t, prefix);
215 0 : strcpy (t + plen, sl->list[i]);
216 0 : if (slen)
217 0 : strcpy (t + plen + llen, suffix);
218 0 : free (sl->list[i]);
219 0 : sl->list[i] = t;
220 : }
221 :
222 : return (sl);
223 : }
224 :
225 : void
226 0 : strlist_print (sl, prefix)
227 : STRINGLIST *sl;
228 : char *prefix;
229 : {
230 0 : register int i;
231 :
232 0 : if (sl == 0)
233 : return;
234 0 : for (i = 0; i < sl->list_len; i++)
235 0 : printf ("%s%s\n", prefix ? prefix : "", sl->list[i]);
236 : }
237 :
238 : void
239 0 : strlist_walk (sl, func)
240 : STRINGLIST *sl;
241 : sh_strlist_map_func_t *func;
242 : {
243 0 : register int i;
244 :
245 0 : if (sl == 0)
246 : return;
247 0 : for (i = 0; i < sl->list_len; i++)
248 0 : if ((*func)(sl->list[i]) < 0)
249 : break;
250 : }
251 :
252 : void
253 0 : strlist_sort (sl)
254 : STRINGLIST *sl;
255 : {
256 0 : if (sl == 0 || sl->list_len == 0 || sl->list == 0)
257 : return;
258 0 : strvec_sort (sl->list);
259 : }
260 :
261 : STRINGLIST *
262 0 : strlist_from_word_list (list, alloc, starting_index, ip)
263 : WORD_LIST *list;
264 : int alloc, starting_index, *ip;
265 : {
266 0 : STRINGLIST *ret;
267 0 : int slen, len;
268 :
269 0 : if (list == 0)
270 : {
271 0 : if (ip)
272 0 : *ip = 0;
273 0 : return ((STRINGLIST *)0);
274 : }
275 0 : slen = list_length (list);
276 0 : ret = (STRINGLIST *)xmalloc (sizeof (STRINGLIST));
277 0 : ret->list = strvec_from_word_list (list, alloc, starting_index, &len);
278 0 : ret->list_size = slen + starting_index;
279 0 : ret->list_len = len;
280 0 : if (ip)
281 0 : *ip = len;
282 : return ret;
283 : }
284 :
285 : WORD_LIST *
286 0 : strlist_to_word_list (sl, alloc, starting_index)
287 : STRINGLIST *sl;
288 : int alloc, starting_index;
289 : {
290 0 : WORD_LIST *list;
291 :
292 0 : if (sl == 0 || sl->list == 0)
293 : return ((WORD_LIST *)NULL);
294 :
295 0 : list = strvec_to_word_list (sl->list, alloc, starting_index);
296 0 : return list;
297 : }
|