| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | /* stringvec.c - functions for managing arrays of strings. */ | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | /* Copyright (C) 2000-2002 Free Software Foundation, Inc.
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    This file is part of GNU Bash, the Bourne Again SHell. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Bash is free software; you can redistribute it and/or modify it under | 
					
						
							|  |  |  |    the terms of the GNU General Public License as published by the Free | 
					
						
							|  |  |  |    Software Foundation; either version 2, or (at your option) any later | 
					
						
							|  |  |  |    version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    Bash is distributed in the hope that it will be useful, but WITHOUT ANY | 
					
						
							|  |  |  |    WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
					
						
							|  |  |  |    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
					
						
							|  |  |  |    for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    You should have received a copy of the GNU General Public License along | 
					
						
							|  |  |  |    with Bash; see the file COPYING.  If not, write to the Free Software | 
					
						
							|  |  |  |    Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #include <config.h>
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #include <bashtypes.h>
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_UNISTD_H)
 | 
					
						
							|  |  |  | #  include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #include <bashansi.h>
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | #include <chartypes.h>
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "shell.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Allocate an array of strings with room for N members. */ | 
					
						
							|  |  |  | char ** | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | strvec_create (n) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      int n; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return ((char **)xmalloc ((n) * sizeof (char *))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | char ** | 
					
						
							|  |  |  | strvec_resize (array, nsize) | 
					
						
							|  |  |  |      char **array; | 
					
						
							|  |  |  |      int nsize; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return ((char **)xrealloc (array, nsize * sizeof (char *))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | /* Return the length of ARRAY, a NULL terminated array of char *. */ | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | strvec_len (array) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      char **array; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; array[i]; i++); | 
					
						
							|  |  |  |   return (i); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Free the contents of ARRAY, a NULL terminated array of char *. */ | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | strvec_flush (array) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      char **array; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (array == 0) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; array[i]; i++) | 
					
						
							|  |  |  |     free (array[i]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | strvec_dispose (array) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      char **array; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (array == 0) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   strvec_flush (array); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   free (array); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | int | 
					
						
							|  |  |  | strvec_remove (array, name) | 
					
						
							|  |  |  |      char **array, *name; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i, j; | 
					
						
							|  |  |  |   char *x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (array == 0) | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; array[i]; i++) | 
					
						
							|  |  |  |     if (STREQ (name, array[i])) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  | 	x = array[i]; | 
					
						
							|  |  |  | 	for (j = i; array[j]; j++) | 
					
						
							|  |  |  | 	  array[j] = array[j + 1]; | 
					
						
							|  |  |  | 	free (x); | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef INCLUDE_UNUSED
 | 
					
						
							|  |  |  | /* Find NAME in ARRAY.  Return the index of NAME, or -1 if not present.
 | 
					
						
							|  |  |  |    ARRAY should be NULL terminated. */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | strvec_search (array, name) | 
					
						
							|  |  |  |      char **array, *name; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; array[i]; i++) | 
					
						
							|  |  |  |     if (STREQ (name, array[i])) | 
					
						
							|  |  |  |       return (i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (-1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | /* Allocate and return a new copy of ARRAY and its contents. */ | 
					
						
							|  |  |  | char ** | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | strvec_copy (array) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      char **array; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							|  |  |  |   int len; | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   char **ret; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   len = strvec_len (array); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   ret = (char **)xmalloc ((len + 1) * sizeof (char *)); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   for (i = 0; array[i]; i++) | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |     ret[i] = savestring (array[i]); | 
					
						
							|  |  |  |   ret[i] = (char *)NULL; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |   return (ret); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Comparison routine for use with qsort() on arrays of strings.  Uses
 | 
					
						
							|  |  |  |    strcoll(3) if available, otherwise it uses strcmp(3). */ | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | strvec_strcmp (s1, s2) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      register char **s1, **s2; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined (HAVE_STRCOLL)
 | 
					
						
							|  |  |  |    return (strcoll (*s1, *s2)); | 
					
						
							|  |  |  | #else /* !HAVE_STRCOLL */
 | 
					
						
							|  |  |  |   int result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((result = **s1 - **s2) == 0) | 
					
						
							|  |  |  |     result = strcmp (*s1, *s2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (result); | 
					
						
							|  |  |  | #endif /* !HAVE_STRCOLL */
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Sort ARRAY, a null terminated array of pointers to strings. */ | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | strvec_sort (array) | 
					
						
							|  |  |  |      char **array; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_strcmp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Cons up a new array of words.  The words are taken from LIST,
 | 
					
						
							|  |  |  |    which is a WORD_LIST *.  If ALLOC is true, everything is malloc'ed, | 
					
						
							|  |  |  |    so you should free everything in this array when you are done. | 
					
						
							|  |  |  |    The array is NULL terminated.  If IP is non-null, it gets the | 
					
						
							|  |  |  |    number of words in the returned array.  STARTING_INDEX says where | 
					
						
							|  |  |  |    to start filling in the returned array; it can be used to reserve | 
					
						
							|  |  |  |    space at the beginning of the array. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char ** | 
					
						
							|  |  |  | strvec_from_word_list (list, alloc, starting_index, ip) | 
					
						
							|  |  |  |      WORD_LIST *list; | 
					
						
							|  |  |  |      int alloc, starting_index, *ip; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int count; | 
					
						
							|  |  |  |   char **array; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   count = list_length (list); | 
					
						
							|  |  |  |   array = (char **)xmalloc ((1 + count + starting_index) * sizeof (char *)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (count = 0; count < starting_index; count++) | 
					
						
							|  |  |  |     array[count] = (char *)NULL; | 
					
						
							|  |  |  |   for (count = starting_index; list; count++, list = list->next) | 
					
						
							|  |  |  |     array[count] = alloc ? savestring (list->word->word) : list->word->word; | 
					
						
							|  |  |  |   array[count] = (char *)NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (ip) | 
					
						
							|  |  |  |     *ip = count; | 
					
						
							|  |  |  |   return (array); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Convert an array of strings into the form used internally by the shell.
 | 
					
						
							|  |  |  |    ALLOC means to allocate new storage for each WORD_DESC in the returned | 
					
						
							|  |  |  |    list rather than copy the values in ARRAY.  STARTING_INDEX says where | 
					
						
							|  |  |  |    in ARRAY to begin. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | WORD_LIST * | 
					
						
							|  |  |  | strvec_to_word_list (array, alloc, starting_index) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      char **array; | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |      int alloc, starting_index; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   WORD_LIST *list; | 
					
						
							|  |  |  |   WORD_DESC *w; | 
					
						
							|  |  |  |   int i, count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (array == 0 || array[0] == 0) | 
					
						
							|  |  |  |     return (WORD_LIST *)NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (count = 0; array[count]; count++) | 
					
						
							|  |  |  |     ; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = starting_index, list = (WORD_LIST *)NULL; i < count; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       w = make_bare_word (alloc ? array[i] : ""); | 
					
						
							|  |  |  |       if (alloc == 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	  free (w->word); | 
					
						
							|  |  |  | 	  w->word = array[i]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       list = make_word_list (w, list); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   return (REVERSE_LIST (list, WORD_LIST *)); | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  | } |