improve of cmpl.
[bush.git] / lib / sh / stringlist.c
blob4eb880918d72ef39e4d43e7869eeefbccf0cf130
1 /* stringlist.c - functions to handle a generic `list of strings' structure */
3 /* Copyright (C) 2000-2019 Free Software Foundation, Inc.
5 This file is part of GNU Bush, the Bourne Again SHell.
7 Bush 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.
12 Bush 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.
17 You should have received a copy of the GNU General Public License
18 along with Bush. If not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
23 #if defined (HAVE_UNISTD_H)
24 # include <unistd.h>
25 #endif
27 #include <stdio.h>
28 #include <bushansi.h>
30 #include "shell.h"
32 #ifdef STRDUP
33 # undef STRDUP
34 #endif
35 #define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
37 /* Allocate a new STRINGLIST, with room for N strings. */
39 STRINGLIST *
40 strlist_create (n)
41 int n;
43 STRINGLIST *ret;
44 register int i;
46 ret = (STRINGLIST *)xmalloc (sizeof (STRINGLIST));
47 if (n)
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;
54 else
56 ret->list = (char **)NULL;
57 ret->list_size = 0;
59 ret->list_len = 0;
60 return ret;
63 STRINGLIST *
64 strlist_resize (sl, n)
65 STRINGLIST *sl;
66 int n;
68 register int i;
70 if (sl == 0)
71 return (sl = strlist_create (n));
73 if (n > sl->list_size)
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;
80 return sl;
83 void
84 strlist_flush (sl)
85 STRINGLIST *sl;
87 if (sl == 0 || sl->list == 0)
88 return;
89 strvec_flush (sl->list);
90 sl->list_len = 0;
93 void
94 strlist_dispose (sl)
95 STRINGLIST *sl;
97 if (sl == 0)
98 return;
99 if (sl->list)
100 strvec_dispose (sl->list);
101 free (sl);
105 strlist_remove (sl, s)
106 STRINGLIST *sl;
107 char *s;
109 int r;
111 if (sl == 0 || sl->list == 0 || sl->list_len == 0)
112 return 0;
114 r = strvec_remove (sl->list, s);
115 if (r)
116 sl->list_len--;
117 return r;
120 STRINGLIST *
121 strlist_copy (sl)
122 STRINGLIST *sl;
124 STRINGLIST *new;
125 register int i;
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)
133 for (i = 0; i < sl->list_size; i++)
134 new->list[i] = STRDUP (sl->list[i]);
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;
144 /* Return a new STRINGLIST with everything from M1 and M2. */
146 STRINGLIST *
147 strlist_merge (m1, m2)
148 STRINGLIST *m1, *m2;
150 STRINGLIST *sl;
151 int i, n, l1, l2;
153 l1 = m1 ? m1->list_len : 0;
154 l2 = m2 ? m2->list_len : 0;
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);
166 /* Make STRINGLIST M1 contain everything in M1 and M2. */
167 STRINGLIST *
168 strlist_append (m1, m2)
169 STRINGLIST *m1, *m2;
171 register int i, n, len1, len2;
173 if (m1 == 0)
174 return (m2 ? strlist_copy (m2) : (STRINGLIST *)0);
176 len1 = m1->list_len;
177 len2 = m2 ? m2->list_len : 0;
179 if (len2)
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;
188 return m1;
191 STRINGLIST *
192 strlist_prefix_suffix (sl, prefix, suffix)
193 STRINGLIST *sl;
194 char *prefix, *suffix;
196 int plen, slen, tlen, llen, i;
197 char *t;
199 if (sl == 0 || sl->list == 0 || sl->list_len == 0)
200 return sl;
202 plen = STRLEN (prefix);
203 slen = STRLEN (suffix);
205 if (plen == 0 && slen == 0)
206 return (sl);
208 for (i = 0; i < sl->list_len; i++)
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;
222 return (sl);
225 void
226 strlist_print (sl, prefix)
227 STRINGLIST *sl;
228 char *prefix;
230 register int i;
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]);
238 void
239 strlist_walk (sl, func)
240 STRINGLIST *sl;
241 sh_strlist_map_func_t *func;
243 register int i;
245 if (sl == 0)
246 return;
247 for (i = 0; i < sl->list_len; i++)
248 if ((*func)(sl->list[i]) < 0)
249 break;
252 void
253 strlist_sort (sl)
254 STRINGLIST *sl;
256 if (sl == 0 || sl->list_len == 0 || sl->list == 0)
257 return;
258 strvec_sort (sl->list, 0);
261 STRINGLIST *
262 strlist_from_word_list (list, alloc, starting_index, ip)
263 WORD_LIST *list;
264 int alloc, starting_index, *ip;
266 STRINGLIST *ret;
267 int slen, len;
269 if (list == 0)
271 if (ip)
272 *ip = 0;
273 return ((STRINGLIST *)0);
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;
285 WORD_LIST *
286 strlist_to_word_list (sl, alloc, starting_index)
287 STRINGLIST *sl;
288 int alloc, starting_index;
290 WORD_LIST *list;
292 if (sl == 0 || sl->list == 0)
293 return ((WORD_LIST *)NULL);
295 list = strvec_to_word_list (sl->list, alloc, starting_index);
296 return list;