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