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 39STRINGLIST * 40strlist_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 63STRINGLIST * 64strlist_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 83void 84strlist_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 93void 94strlist_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 104int 105strlist_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 120STRINGLIST * 121strlist_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 146STRINGLIST * 147strlist_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. */ 167STRINGLIST * 168strlist_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 191STRINGLIST * 192strlist_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 225void 226strlist_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 238void 239strlist_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 252void 253strlist_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 261STRINGLIST * 262strlist_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 285WORD_LIST * 286strlist_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} 298